issue new refresh tokens for clients who are configured for it, closes #408

pull/803/merge
Justin Richer 2015-05-13 18:01:49 -04:00
parent 5b02e18f7c
commit aeed2fa003
3 changed files with 46 additions and 31 deletions

View File

@ -105,6 +105,7 @@
"refresh": "refresh",
"refresh-tokens": "Refresh Tokens",
"refresh-tokens-issued": "Refresh tokens are issued for this client",
"refresh-tokens-issued-help": "This will add the offline_access scope to the client's scopes.",
"refresh-tokens-reused": "Refresh tokens for this client are re-used",
"refresh-tokens-no-expire": "Refresh tokens do not time out",
"registered": "Registered at",

View File

@ -543,6 +543,7 @@
<div>
<input type="checkbox" id="allowRefresh" <%-(allowRefresh == true ? 'checked' : '')%>>
<label for="allowRefresh" class="checkbox" data-i18n="client.client-form.refresh-tokens-issued">Refresh tokens are issued for this client</label>
<p class="help-block" data-i18n="client.client-form.refresh-tokens-issued-help">This will add the offline_access scope to the client's scopes.</p>
</div>
</div>
</div>

View File

@ -170,33 +170,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
// attach a refresh token, if this client is allowed to request them and the user gets the offline scope
if (client.isAllowRefresh() && token.getScope().contains(SystemScopeService.OFFLINE_ACCESS)) {
OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken();
JWTClaimsSet refreshClaims = new JWTClaimsSet();
// make it expire if necessary
if (client.getRefreshTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L));
refreshToken.setExpiration(expiration);
refreshClaims.setExpirationTime(expiration);
}
// set a random identifier
refreshClaims.setJWTID(UUID.randomUUID().toString());
// TODO: add issuer fields, signature to JWT
PlainJWT refreshJwt = new PlainJWT(refreshClaims);
refreshToken.setJwt(refreshJwt);
//Add the authentication
refreshToken.setAuthenticationHolder(authHolder);
refreshToken.setClient(client);
// save the token first so that we can set it to a member of the access token (NOTE: is this step necessary?)
OAuth2RefreshTokenEntity savedRefreshToken = tokenRepository.saveRefreshToken(refreshToken);
OAuth2RefreshTokenEntity savedRefreshToken = createRefreshToken(client, authHolder);
token.setRefreshToken(savedRefreshToken);
}
@ -229,6 +203,38 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
throw new AuthenticationCredentialsNotFoundException("No authentication credentials found");
}
private OAuth2RefreshTokenEntity createRefreshToken(ClientDetailsEntity client, AuthenticationHolderEntity authHolder) {
OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken();
JWTClaimsSet refreshClaims = new JWTClaimsSet();
// make it expire if necessary
if (client.getRefreshTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L));
refreshToken.setExpiration(expiration);
refreshClaims.setExpirationTime(expiration);
}
// set a random identifier
refreshClaims.setJWTID(UUID.randomUUID().toString());
// TODO: add issuer fields, signature to JWT
PlainJWT refreshJwt = new PlainJWT(refreshClaims);
refreshToken.setJwt(refreshJwt);
//Add the authentication
refreshToken.setAuthenticationHolder(authHolder);
refreshToken.setClient(client);
// save the token first so that we can set it to a member of the access token (NOTE: is this step necessary?)
OAuth2RefreshTokenEntity savedRefreshToken = tokenRepository.saveRefreshToken(refreshToken);
return savedRefreshToken;
}
@Override
public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException {
@ -263,9 +269,6 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
throw new InvalidTokenException("Expired refresh token: " + refreshTokenValue);
}
// TODO: have the option to recycle the refresh token here, too
// for now, we just reuse it as long as it's valid, which is the original intent
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
// get the stored scopes from the authentication holder's authorization request; these are the scopes associated with the refresh token
@ -302,7 +305,17 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
token.setExpiration(expiration);
}
token.setRefreshToken(refreshToken);
if (client.isReuseRefreshToken()) {
// if the client re-uses refresh tokens, do that
token.setRefreshToken(refreshToken);
} else {
// otherwise, make a new refresh token
OAuth2RefreshTokenEntity newRefresh = createRefreshToken(client, authHolder);
token.setRefreshToken(newRefresh);
// clean up the old refresh token
tokenRepository.removeRefreshToken(refreshToken);
}
token.setAuthenticationHolder(authHolder);