Skip to content

Commit 7c6fda7

Browse files
committed
Add dynamic CallCredentials helpers
Fixes #552
1 parent 3b299c6 commit 7c6fda7

File tree

1 file changed

+86
-6
lines changed

1 file changed

+86
-6
lines changed

grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/security/CallCredentialsHelper.java

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Base64;
2828
import java.util.Map;
2929
import java.util.concurrent.Executor;
30+
import java.util.function.Supplier;
3031

3132
import javax.annotation.Nullable;
3233

@@ -159,7 +160,8 @@ public static StubTransformer mappedCredentialsStubTransformer(
159160
}
160161

161162
/**
162-
* Creates new call credentials with the given token for bearer auth.
163+
* Creates new call credentials with the given token for bearer auth. Use this method if you have a permanent token
164+
* or only use the call credentials for a single call/while the token is valid.
163165
*
164166
* <p>
165167
* <b>Note:</b> This method uses experimental grpc-java-API features.
@@ -174,6 +176,23 @@ public static CallCredentials bearerAuth(final String token) {
174176
return authorizationHeader(BEARER_AUTH_PREFIX + token);
175177
}
176178

179+
/**
180+
* Creates new call credentials with the given token source for bearer auth. Use this method if you derive the token
181+
* from the active context (e.g. currently logged in user) or dynamically obtain it from the authentication server.
182+
*
183+
* <p>
184+
* <b>Note:</b> This method uses experimental grpc-java-API features.
185+
* </p>
186+
*
187+
* @param tokenSource the bearer token source to use
188+
* @return The newly created bearer auth credentials.
189+
* @see SecurityConstants#BEARER_AUTH_PREFIX
190+
* @see #authorizationHeader(Supplier)
191+
*/
192+
public static CallCredentials bearerAuth(final Supplier<String> tokenSource) {
193+
return authorizationHeader(() -> BEARER_AUTH_PREFIX + tokenSource);
194+
}
195+
177196
/**
178197
* Creates new call credentials with the given username and password for basic auth.
179198
*
@@ -228,32 +247,55 @@ public static String encodeBasicAuth(final String username, final String passwor
228247
* @see #authorizationHeaders(Metadata)
229248
*/
230249
public static CallCredentials authorizationHeader(final String authorization) {
231-
requireNonNull(authorization);
250+
requireNonNull(authorization, "authorization");
232251
final Metadata extraHeaders = new Metadata();
233252
extraHeaders.put(AUTHORIZATION_HEADER, authorization);
234253
return authorizationHeaders(extraHeaders);
235254
}
236255

256+
/**
257+
* Creates new call credentials with the given authorization information source.
258+
*
259+
* <p>
260+
* <b>Note:</b> This method uses experimental grpc-java-API features.
261+
* </p>
262+
*
263+
* @param authorizationSource The authorization source to use. The authorization usually starts with the scheme such
264+
* as as {@code "Basic "} or {@code "Bearer "} followed by the actual authentication information.
265+
* @return The newly created call credentials.
266+
* @see SecurityConstants#AUTHORIZATION_HEADER
267+
* @see #authorizationHeaders(Supplier)
268+
*/
269+
public static CallCredentials authorizationHeader(final Supplier<String> authorizationSource) {
270+
requireNonNull(authorizationSource, "authorizationSource");
271+
272+
return authorizationHeaders(() -> {
273+
final Metadata extraHeaders = new Metadata();
274+
extraHeaders.put(AUTHORIZATION_HEADER, authorizationSource.get());
275+
return extraHeaders;
276+
});
277+
}
278+
237279
/**
238280
* Creates new call credentials with the given static authorization headers.
239281
*
240282
* @param authorizationHeaders The authorization headers to use.
241283
* @return The newly created call credentials.
242284
*/
243285
public static CallCredentials authorizationHeaders(final Metadata authorizationHeaders) {
244-
return new StaticSecurityHeaderCallCredentials(requireNonNull(authorizationHeaders));
286+
return new StaticSecurityHeaderCallCredentials(authorizationHeaders);
245287
}
246288

247289
/**
248-
* The static security header {@link CallCredentials} simply add a set of predefined headers to the call. Their
290+
* The static security header {@link CallCredentials} simply adds a set of predefined headers to the call. Their
249291
* specific meaning is server specific. This implementation can be used, for example, for BasicAuth.
250292
*/
251293
private static final class StaticSecurityHeaderCallCredentials extends CallCredentials {
252294

253295
private final Metadata extraHeaders;
254296

255-
StaticSecurityHeaderCallCredentials(final Metadata extraHeaders) {
256-
this.extraHeaders = requireNonNull(extraHeaders, "extraHeaders");
297+
StaticSecurityHeaderCallCredentials(final Metadata authorizationHeaders) {
298+
this.extraHeaders = requireNonNull(authorizationHeaders, "authorizationHeaders");
257299
}
258300

259301
@Override
@@ -272,6 +314,44 @@ public String toString() {
272314

273315
}
274316

317+
/**
318+
* Creates new call credentials with the given authorization headers source.
319+
*
320+
* @param authorizationHeadersSupplier The authorization headers source to use.
321+
* @return The newly created call credentials.
322+
*/
323+
public static CallCredentials authorizationHeaders(final Supplier<Metadata> authorizationHeadersSupplier) {
324+
return new DynamicSecurityHeaderCallCredentials(authorizationHeadersSupplier);
325+
}
326+
327+
/**
328+
* The dynamic security header {@link CallCredentials} simply adds a set of dynamic headers to the call. Their
329+
* specific meaning is server specific. This implementation can be used, for example, for BasicAuth.
330+
*/
331+
private static final class DynamicSecurityHeaderCallCredentials extends CallCredentials {
332+
333+
private final Supplier<Metadata> extraHeadersSupplier;
334+
335+
DynamicSecurityHeaderCallCredentials(final Supplier<Metadata> authorizationHeadersSupplier) {
336+
this.extraHeadersSupplier = requireNonNull(authorizationHeadersSupplier, "authorizationHeadersSupplier");
337+
}
338+
339+
@Override
340+
public void applyRequestMetadata(final RequestInfo requestInfo, final Executor appExecutor,
341+
final MetadataApplier applier) {
342+
applier.apply(this.extraHeadersSupplier.get());
343+
}
344+
345+
@Override
346+
public void thisUsesUnstableApi() {} // API evolution in progress
347+
348+
@Override
349+
public String toString() {
350+
return "DynamicSecurityHeaderCallCredentials [extraHeadersSupplier=" + this.extraHeadersSupplier + "]";
351+
}
352+
353+
}
354+
275355
/**
276356
* Checks whether the given security level provides privacy for all data being send on the connection.
277357
*

0 commit comments

Comments
 (0)