Permalink
Browse files

SECOAUTH-279: DefaultTokenServices detect when a refresh token is exp…

…ired

DefaultTokenServices detect when a refresh token is expired and replace it.

The original fix only dealt with null refresh tokens.  A better(?) solution
is to detect an expired refresh token and replace it during the
createAccessToken stage of authentication. 
  • Loading branch information...
Hons authored and dsyer committed Oct 26, 2012
1 parent dd13da2 commit c0c1b39c1bbd94b466cadea197809d91b88f6329
@@ -95,6 +95,13 @@ public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication)
if (refreshToken == null) {
refreshToken = createRefreshToken(authentication);
}
+ // But the refresh token itself might need to be re-issued if it has expired.
+ else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
+ ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken) refreshToken;
+ if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {
+ refreshToken = createRefreshToken(authentication);
+ }
+ }
OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);
tokenStore.storeAccessToken(accessToken, authentication);
@@ -119,10 +126,10 @@ public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, Authorizat
OAuth2Authentication authentication = tokenStore.readAuthenticationForRefreshToken(refreshToken);
String clientId = authentication.getAuthorizationRequest().getClientId();
- if (clientId==null || !clientId.equals(request.getClientId())) {
- throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue);
+ if (clientId == null || !clientId.equals(request.getClientId())) {
+ throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue);
}
-
+
// clear out any access tokens already associated with the refresh token.
tokenStore.removeAccessTokenUsingRefreshToken(refreshToken);
@@ -4,6 +4,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collections;
@@ -13,6 +14,7 @@
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
+import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
@@ -65,6 +67,24 @@ public void testExpiredRefreshToken() throws Exception {
getTokenServices().refreshAccessToken(firstAccessToken.getRefreshToken().getValue(), new DefaultAuthorizationRequest("id", null));
}
+ @Test
+ public void testExpiredRefreshTokenIsRenewedWithNewAccessToken() throws Exception {
+ OAuth2Authentication expectedAuthentication = new OAuth2Authentication(new DefaultAuthorizationRequest("id",
+ Collections.singleton("read")), new TestAuthentication("test2", false));
+ DefaultOAuth2AccessToken firstAccessToken = (DefaultOAuth2AccessToken) getTokenServices().createAccessToken(
+ expectedAuthentication);
+ assertNotNull(firstAccessToken.getRefreshToken());
+ // Make it expire (and rely on mutable state in volatile token store)
+ ReflectionTestUtils.setField(firstAccessToken.getRefreshToken(), "expiration",
+ new Date(System.currentTimeMillis() - 1000));
+ firstAccessToken.setExpiration(new Date(System.currentTimeMillis() - 1000));
+ DefaultOAuth2AccessToken secondAccessToken = (DefaultOAuth2AccessToken) getTokenServices().createAccessToken(
+ expectedAuthentication);
+ ExpiringOAuth2RefreshToken refreshToken = (ExpiringOAuth2RefreshToken) secondAccessToken.getRefreshToken();
+ assertNotNull(refreshToken);
+ assertTrue(refreshToken.getExpiration().getTime() > System.currentTimeMillis());
+ }
+
@Test
public void testDifferentRefreshTokenMaintainsState() throws Exception {
// create access token

0 comments on commit c0c1b39

Please sign in to comment.