@@ -111,7 +111,7 @@ public Response call(String uri, ConnectorContext context, HttpServletRequest re
111
111
FakeHttpServletResponse wrappedRes = new FakeHttpServletResponse (res );
112
112
113
113
Response resp = null ;
114
- boolean newlyLoaded = false ;
114
+ boolean newlyLoaded = false , tokensChanged = false ;
115
115
116
116
context .setCommitResponseOnAuthenticationError (false );
117
117
@@ -193,21 +193,37 @@ public Response call(String uri, ConnectorContext context, HttpServletRequest re
193
193
logger .debug ("Trying to refresh access token - using refresh token " + getRefreshToken ());
194
194
try
195
195
{
196
- String oldToken = getAccessToken ();
197
- String newToken = doRefresh (endpointId );
196
+ String oldToken = getAccessToken (), oldRefreshToken = getRefreshToken ();
197
+ JSONObject json = doRefresh (endpointId );
198
+ String newToken = json .getString ("access_token" );
199
+ if (logger .isDebugEnabled ())
200
+ logger .debug ("Parsed access token: " + newToken );
198
201
if (newToken != null && !newToken .equals (oldToken ))
199
202
{
200
203
if (logger .isDebugEnabled ())
201
204
logger .debug ("Got new access token " + newToken + " - retrying request for " + uri );
202
205
connectorSession .setParameter (OAuth2Authenticator .CS_PARAM_ACCESS_TOKEN , newToken );
203
- saveTokens (endpointId , req );
206
+ tokensChanged = true ;
207
+ // Retry the call
204
208
wrappedRes .reset ();
205
209
resp = callInternal (uri , context , req , wrappedRes );
206
210
}
207
211
else
208
212
{
209
213
logger .debug ("No token returned or token not updated" );
210
214
}
215
+ // In some providers the refresh token may also change when a refresh occurs
216
+ if (json .has ("refresh_token" ))
217
+ {
218
+ String refreshToken = json .getString ("refresh_token" );
219
+ if (refreshToken != null && !refreshToken .equals (oldRefreshToken ))
220
+ {
221
+ if (logger .isDebugEnabled ())
222
+ logger .debug ("Got new refresh token " + refreshToken );
223
+ connectorSession .setParameter (OAuth2Authenticator .CS_PARAM_REFRESH_TOKEN , refreshToken );
224
+ tokensChanged = true ;
225
+ }
226
+ }
211
227
}
212
228
catch (TokenRefreshException e )
213
229
{
@@ -216,6 +232,18 @@ public Response call(String uri, ConnectorContext context, HttpServletRequest re
216
232
"Unable to refresh token" ,
217
233
e );
218
234
}
235
+ catch (JSONException e )
236
+ {
237
+ writeError (wrappedRes , ResponseStatus .STATUS_INTERNAL_SERVER_ERROR ,
238
+ "ERR_MISSING_ACCESS_TOKEN" ,
239
+ "Unable to retrieve access token from provider response" ,
240
+ e );
241
+ }
242
+
243
+ if (tokensChanged )
244
+ {
245
+ saveTokens (endpointId , req );
246
+ }
219
247
}
220
248
221
249
copyResponseContent (resp , wrappedRes , res , true );
@@ -441,15 +469,15 @@ protected void applyRequestAuthentication(RemoteClient remoteClient, ConnectorCo
441
469
}
442
470
}
443
471
444
- // TODO replace AuthenticationException with something else
445
- protected String doRefresh (String endpointId ) throws TokenRefreshException
472
+ protected JSONObject doRefresh (String endpointId ) throws TokenRefreshException
446
473
{
447
474
String refreshToken = getRefreshToken ();
448
475
EndpointDescriptor epd = getEndpointDescriptor (endpointId );
449
476
450
477
// First try to get the client-id and access-token-url from the endpoint, then from the connector
451
478
// TODO Make these strings constants in a Descriptor sub-class or interface
452
479
String clientId = getDescriptorProperty ("client-id" , epd );
480
+ String clientSecret = getDescriptorProperty ("client-secret" , epd );
453
481
String tokenUrl = getDescriptorProperty ("access-token-url" , epd );
454
482
/*
455
483
RemoteClient remoteClient = buildRemoteClient(tokenUrl);
@@ -476,6 +504,7 @@ protected String doRefresh(String endpointId) throws TokenRefreshException
476
504
method .addParameter ("grant_type" , "refresh_token" );
477
505
method .addParameter ("refresh_token" , refreshToken );
478
506
method .addParameter ("client_id" , clientId );
507
+ method .addParameter ("client_secret" , clientSecret );
479
508
method .addRequestHeader ("Accept" , Format .JSON .mimetype ());
480
509
481
510
int statusCode ;
@@ -488,11 +517,10 @@ protected String doRefresh(String endpointId) throws TokenRefreshException
488
517
489
518
if (statusCode == Status .STATUS_OK )
490
519
{
491
- String accessToken ;
520
+ JSONObject json ;
492
521
try
493
522
{
494
- JSONObject json = new JSONObject (tokenResp );
495
- accessToken = json .getString ("access_token" );
523
+ json = new JSONObject (tokenResp );
496
524
}
497
525
catch (JSONException jErr )
498
526
{
@@ -502,30 +530,23 @@ protected String doRefresh(String endpointId) throws TokenRefreshException
502
530
"Unable to retrieve access token from provider response" , jErr );
503
531
}
504
532
505
- if (logger .isDebugEnabled ())
506
- logger .debug ("Parsed access token: " + accessToken );
507
-
508
- return accessToken ;
533
+ return json ;
509
534
}
510
535
else
511
536
{
512
537
if (logger .isDebugEnabled ())
513
538
logger .debug ("Token refresh failed, received response code: " + statusCode );
514
539
logger .debug ("Received response " + tokenResp );
515
- return null ;
540
+ throw new TokenRefreshException ( "Token refresh failed, received response code: " + statusCode ) ;
516
541
}
517
542
}
518
543
catch (HttpException e )
519
544
{
520
- // TODO Auto-generated catch block
521
- e .printStackTrace ();
522
- return null ;
545
+ throw new TokenRefreshException ("Error when refreshing tokens" , e );
523
546
}
524
547
catch (IOException e )
525
548
{
526
- // TODO Auto-generated catch block
527
- e .printStackTrace ();
528
- return null ;
549
+ throw new TokenRefreshException ("Error when refreshing tokens" , e );
529
550
}
530
551
}
531
552
0 commit comments