31
31
* an access token from the IAM token service via the "POST /identity/token" operation.
32
32
* When the access token expires, a new access token will be fetched.
33
33
*/
34
- public class IamAuthenticator extends TokenRequestBasedAuthenticator < IamToken , IamToken > implements Authenticator {
34
+ public class IamAuthenticator extends IamRequestBasedAuthenticator implements Authenticator {
35
35
private static final String DEFAULT_IAM_URL = "https://iam.cloud.ibm.com" ;
36
36
private static final String OPERATION_PATH = "/identity/token" ;
37
- private static final String GRANT_TYPE = "grant_type" ;
38
- private static final String REQUEST_GRANT_TYPE = "urn:ibm:params:oauth:grant-type:apikey" ;
39
- private static final String API_KEY = "apikey" ;
40
- private static final String RESPONSE_TYPE = "response_type" ;
41
- private static final String CLOUD_IAM = "cloud_iam" ;
42
- private static final String SCOPE = "scope" ;
43
37
44
38
// Properties specific to an IAM authenticator.
45
- private String url ;
46
39
private String apikey ;
47
- private String scope ;
48
- private String clientId ;
49
- private String clientSecret ;
50
-
51
- // This is the value of the Authorization header we'll use when interacting with the token server.
52
- private String cachedAuthorizationHeader = null ;
53
40
54
41
/**
55
42
* This Builder class is used to construct IamAuthenticator instances.
56
43
*/
57
44
public static class Builder {
58
- private String url ;
59
45
private String apikey ;
46
+ private String url ;
60
47
private String scope ;
61
48
private String clientId ;
62
49
private String clientSecret ;
@@ -70,12 +57,12 @@ public Builder() { }
70
57
71
58
// Builder ctor which copies config from an existing authenticator instance.
72
59
private Builder (IamAuthenticator obj ) {
73
- this .url = obj .url ;
74
60
this .apikey = obj .apikey ;
75
- this .scope = obj .scope ;
76
- this .clientId = obj .clientId ;
77
- this .clientSecret = obj .clientSecret ;
78
61
62
+ this .url = obj .getURL ();
63
+ this .scope = obj .getScope ();
64
+ this .clientId = obj .getClientId ();
65
+ this .clientSecret = obj .getClientSecret ();
79
66
this .disableSSLVerification = obj .getDisableSSLVerification ();
80
67
this .headers = obj .getHeaders ();
81
68
this .proxy = obj .getProxy ();
@@ -91,6 +78,16 @@ public IamAuthenticator build() {
91
78
return new IamAuthenticator (this );
92
79
}
93
80
81
+ /**
82
+ * Sets the apikey property.
83
+ * @param apikey the apikey to use when retrieving an access token
84
+ * @return the Builder
85
+ */
86
+ public Builder apikey (String apikey ) {
87
+ this .apikey = apikey ;
88
+ return this ;
89
+ }
90
+
94
91
/**
95
92
* Sets the url property.
96
93
* @param url the base url to use with the IAM token service
@@ -121,16 +118,6 @@ public Builder clientSecret(String clientSecret) {
121
118
return this ;
122
119
}
123
120
124
- /**
125
- * Sets the apikey property.
126
- * @param apikey the apikey to use when retrieving an access token
127
- * @return the Builder
128
- */
129
- public Builder apikey (String apikey ) {
130
- this .apikey = apikey ;
131
- return this ;
132
- }
133
-
134
121
/**
135
122
* Sets the scope property.
136
123
* @param scope the scope to use when retrieving an access token
@@ -195,12 +182,11 @@ protected IamAuthenticator() {
195
182
* @param builder the Builder instance containing the configuration to be used
196
183
*/
197
184
protected IamAuthenticator (Builder builder ) {
198
- this .url = builder .url ;
199
185
this .apikey = builder .apikey ;
200
- this .scope = builder .scope ;
201
- this .clientId = builder .clientId ;
202
- this .clientSecret = builder .clientSecret ;
203
186
187
+ setURL (builder .url );
188
+ setScope (builder .scope );
189
+ setClientIdAndSecret (builder .clientId , builder .clientSecret );
204
190
setDisableSSLVerification (builder .disableSSLVerification );
205
191
setHeaders (builder .headers );
206
192
setProxy (builder .proxy );
@@ -319,8 +305,8 @@ public static IamAuthenticator fromConfiguration(Map<String, String> config) {
319
305
}
320
306
321
307
return new Builder ()
322
- .url (config .get (PROPNAME_URL ))
323
308
.apikey (apikey )
309
+ .url (config .get (PROPNAME_URL ))
324
310
.scope (config .get (PROPNAME_SCOPE ))
325
311
.clientId (config .get (PROPNAME_CLIENT_ID ))
326
312
.clientSecret (config .get (PROPNAME_CLIENT_SECRET ))
@@ -350,7 +336,8 @@ public static IamAuthenticator fromConfiguration(Map<String, String> config) {
350
336
protected void init (String apikey , String url , String clientId , String clientSecret ,
351
337
boolean disableSSLVerification , Map <String , String > headers , String scope ) {
352
338
this .apikey = apikey ;
353
- this .url = url ;
339
+
340
+ setURL (url );
354
341
setClientIdAndSecret (clientId , clientSecret );
355
342
setScope (scope );
356
343
this .validate ();
@@ -361,13 +348,14 @@ protected void init(String apikey, String url, String clientId, String clientSec
361
348
362
349
@ Override
363
350
public void validate () {
351
+ super .validate ();
364
352
365
- if (StringUtils .isEmpty (this .url )) {
353
+ if (StringUtils .isEmpty (this .getURL () )) {
366
354
// If no base URL was configured, then use the default IAM base URL.
367
- this .url = DEFAULT_IAM_URL ;
368
- } else if ( this . url . endsWith ( OPERATION_PATH )) {
355
+ this .setURL ( DEFAULT_IAM_URL ) ;
356
+ } else {
369
357
// Canonicalize the URL by removing the operation path from it if present.
370
- this .url = this . url . substring ( 0 , this .url . length () - OPERATION_PATH . length ( ));
358
+ this .setURL ( StringUtils . removeEnd ( this .getURL (), OPERATION_PATH ));
371
359
}
372
360
373
361
if (StringUtils .isEmpty (this .apikey )) {
@@ -377,21 +365,6 @@ public void validate() {
377
365
if (CredentialUtils .hasBadStartOrEndChar (this .apikey )) {
378
366
throw new IllegalArgumentException (String .format (ERRORMSG_PROP_INVALID , "apikey" ));
379
367
}
380
-
381
- if (StringUtils .isEmpty (getUsername ()) && StringUtils .isEmpty (getPassword ())) {
382
- // both empty is ok.
383
- } else {
384
- if (StringUtils .isEmpty (getUsername ())) {
385
- throw new IllegalArgumentException (String .format (ERRORMSG_PROP_MISSING , "clientId" ));
386
- }
387
- if (StringUtils .isEmpty (getPassword ())) {
388
- throw new IllegalArgumentException (String .format (ERRORMSG_PROP_MISSING , "clientSecret" ));
389
- }
390
- }
391
-
392
- // Assuming everything validates clean, let's cache the basic auth header if
393
- // the clientId/clientSecret properties are configured.
394
- this .cachedAuthorizationHeader = constructBasicAuthHeader (this .clientId , this .clientSecret );
395
368
}
396
369
397
370
@ Override
@@ -406,38 +379,6 @@ public String getApiKey() {
406
379
return this .apikey ;
407
380
}
408
381
409
- /**
410
- * @return the URL configured on this Authenticator.
411
- */
412
- public String getURL () {
413
- return this .url ;
414
- }
415
-
416
- /**
417
- * Sets the URL on this Authenticator.
418
- * @param url the URL representing the IAM token server endpoint
419
- */
420
- public void setURL (String url ) {
421
- if (StringUtils .isEmpty (url )) {
422
- url = DEFAULT_IAM_URL ;
423
- }
424
- this .url = url ;
425
- }
426
-
427
- /**
428
- * @return the clientId configured on this Authenticator.
429
- */
430
- public String getClientId () {
431
- return this .clientId ;
432
- }
433
-
434
- /**
435
- * @return the clientSecret configured on this Authenticator.
436
- */
437
- public String getClientSecret () {
438
- return this .clientSecret ;
439
- }
440
-
441
382
/**
442
383
* @return the basic auth username (clientId) configured for this Authenticator.
443
384
*
@@ -470,32 +411,6 @@ public void setBasicAuthInfo(String clientId, String clientSecret) {
470
411
setClientIdAndSecret (clientId , clientSecret );
471
412
}
472
413
473
- /**
474
- * Sets the clientId and clientSecret on this Authenticator.
475
- * @param clientId the clientId to use in interactions with the token server
476
- * @param clientSecret the clientSecret to use in interactions with the token server
477
- */
478
- public void setClientIdAndSecret (String clientId , String clientSecret ) {
479
- this .clientId = clientId ;
480
- this .clientSecret = clientSecret ;
481
- this .validate ();
482
- }
483
-
484
- /**
485
- * @return the scope parameter
486
- */
487
- public String getScope () {
488
- return this .scope ;
489
- }
490
-
491
- /**
492
- * Sets the "scope" parameter to use when fetching the bearer token from the IAM token server.
493
- * @param value a space seperated string that makes up the scope parameter.
494
- */
495
- public void setScope (String value ) {
496
- this .scope = value ;
497
- }
498
-
499
414
/**
500
415
* Fetches an IAM access token for the apikey using the configured URL.
501
416
*
@@ -504,23 +419,22 @@ public void setScope(String value) {
504
419
@ Override
505
420
public IamToken requestToken () {
506
421
// Form a POST request to retrieve the access token.
507
- RequestBuilder builder = RequestBuilder .post (RequestBuilder .resolveRequestUrl (this .url , OPERATION_PATH ));
422
+ RequestBuilder builder = RequestBuilder .post (RequestBuilder .resolveRequestUrl (this .getURL () , OPERATION_PATH ));
508
423
509
424
// Now add the Content-Type and (optionally) the Authorization header to the token server request.
510
425
builder .header (HttpHeaders .CONTENT_TYPE , HttpMediaType .APPLICATION_FORM_URLENCODED );
511
- if (StringUtils .isNotEmpty (this .cachedAuthorizationHeader )) {
512
- builder .header (HttpHeaders .AUTHORIZATION , this .cachedAuthorizationHeader );
513
- }
426
+ addAuthorizationHeader (builder );
514
427
515
428
// Build the form request body.
516
429
FormBody formBody ;
517
430
final FormBody .Builder formBodyBuilder = new FormBody .Builder ()
518
- .add (GRANT_TYPE , REQUEST_GRANT_TYPE )
519
- .add (API_KEY , apikey )
520
- .add (RESPONSE_TYPE , CLOUD_IAM );
521
- // Add the scope param if it's not empty
431
+ .add ("grant_type" , "urn:ibm:params:oauth:grant-type:apikey" )
432
+ .add ("apikey" , getApiKey ())
433
+ .add ("response_type" , "cloud_iam" );
434
+
435
+ // Add the scope param if it's not empty.
522
436
if (!StringUtils .isEmpty (getScope ())) {
523
- formBodyBuilder .add (SCOPE , getScope ());
437
+ formBodyBuilder .add ("scope" , getScope ());
524
438
}
525
439
formBody = formBodyBuilder .build ();
526
440
builder .body (formBody );
0 commit comments