From ef4482249cffc027bc976d2cb60996d860b1b115 Mon Sep 17 00:00:00 2001 From: Amanda Anganes Date: Fri, 9 Aug 2013 11:48:58 -0400 Subject: [PATCH] Dyn-reg endpoint now creates the registration access token from scratch instead of calling token services; token services no longer needs to check for RAT scope to avoid expiring RATs --- .../DefaultOAuth2ProviderTokenService.java | 10 ++-- .../ClientDynamicRegistrationEndpoint.java | 55 +++++++++++++++++-- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java index 52ff685a6..fefa299a9 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java @@ -144,12 +144,10 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi Set scopes = Sets.newHashSet(clientAuth.getScope()); token.setScope(scopes); - // make it expire if necessary - exclude Registration Tokens as these should always be long-lived - if (!scopes.contains(OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE)) { - if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) { - Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L)); - token.setExpiration(expiration); - } + // make it expire if necessary + if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) { + Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L)); + token.setExpiration(expiration); } // attach the authorization so that we can look it up later diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java index 14fb0df54..dbacb3d27 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientDynamicRegistrationEndpoint.java @@ -16,15 +16,20 @@ ******************************************************************************/ package org.mitre.openid.connect.web; +import java.util.Date; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.TimeUnit; +import org.mitre.jwt.signer.service.JwtSigningAndValidationService; +import org.mitre.oauth2.model.AuthenticationHolderEntity; import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; import org.mitre.oauth2.model.OAuth2AccessTokenEntity; import org.mitre.oauth2.model.RegisteredClient; import org.mitre.oauth2.model.SystemScope; +import org.mitre.oauth2.repository.AuthenticationHolderRepository; import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.oauth2.service.OAuth2TokenEntityService; import org.mitre.oauth2.service.SystemScopeService; @@ -47,8 +52,13 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; @Controller @RequestMapping(value = "register") @@ -59,6 +69,15 @@ public class ClientDynamicRegistrationEndpoint { @Autowired private OAuth2TokenEntityService tokenService; + + @Autowired + private JwtSigningAndValidationService jwtService; + + @Autowired + private ConfigurationPropertiesBean configBean; + + @Autowired + private AuthenticationHolderRepository authenticationHolderRepository; @Autowired private SystemScopeService scopeService; @@ -320,12 +339,40 @@ public class ClientDynamicRegistrationEndpoint { private OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client) throws AuthenticationException { Map authorizationParameters = Maps.newHashMap(); - OAuth2Request storedRequest = new OAuth2Request(authorizationParameters, client.getClientId(), + OAuth2Request clientAuth = new OAuth2Request(authorizationParameters, client.getClientId(), Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true, Sets.newHashSet(OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE), null, null, null); - OAuth2Authentication authentication = new OAuth2Authentication(storedRequest, null); - OAuth2AccessTokenEntity registrationAccessToken = (OAuth2AccessTokenEntity) tokenService.createAccessToken(authentication); - return registrationAccessToken; + OAuth2Authentication authentication = new OAuth2Authentication(clientAuth, null); + + OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); + token.setClient(client); + token.setScope(Sets.newHashSet(OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE)); + + AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); + authHolder.setAuthentication(authentication); + authHolder = authenticationHolderRepository.save(authHolder); + token.setAuthenticationHolder(authHolder); + + JWTClaimsSet claims = new JWTClaimsSet(); + + claims.setAudience(Lists.newArrayList(client.getClientId())); + claims.setIssuer(configBean.getIssuer()); + claims.setIssueTime(new Date()); + claims.setExpirationTime(token.getExpiration()); + claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it + + // TODO: use client's default signing algorithm + JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm(); + SignedJWT signed = new SignedJWT(new JWSHeader(signingAlg), claims); + + jwtService.signJwt(signed); + + token.setJwt(signed); + + tokenService.saveAccessToken(token); + + return token; + } }