From 530c3a75eea5e3665aa6dc2bbb678474d48aacd7 Mon Sep 17 00:00:00 2001 From: Amanda Anganes Date: Mon, 24 Jun 2013 09:44:59 -0400 Subject: [PATCH] Applyed refactoring --- .../IntrospectingTokenService.java | 26 ++++++----- .../oauth2/model/AuthorizationCodeEntity.java | 22 ++++----- .../AuthorizationCodeRepository.java | 4 +- .../impl/JpaAuthorizationCodeRepository.java | 6 +-- ...DefaultOAuth2AuthorizationCodeService.java | 8 ++-- .../DefaultOAuth2ProviderTokenService.java | 13 +++--- .../oauth2/token/ChainedTokenGranter.java | 31 ++++++------- .../token/JwtAssertionTokenGranter.java | 13 +++--- .../oauth2/view/TokenIntrospectionView.java | 2 +- .../web/OAuthConfirmationController.java | 4 +- .../mitre/oauth2/web/RevocationEndpoint.java | 4 +- ....java => ConnectOAuth2RequestFactory.java} | 31 +++++++------ .../connect/token/ConnectTokenEnhancer.java | 4 +- .../token/TofuUserApprovalHandler.java | 46 +++++++++---------- .../ClientDynamicRegistrationEndpoint.java | 22 ++++----- .../openid/connect/web/UserInfoEndpoint.java | 4 +- .../db/tables/hsql_database_tables.sql | 2 +- .../db/tables/mysql_database_tables.sql | 2 +- .../webapp/WEB-INF/application-context.xml | 10 +++- spring-security-oauth | 2 +- 20 files changed, 133 insertions(+), 123 deletions(-) rename openid-connect-server/src/main/java/org/mitre/openid/connect/{ConnectOAuth2RequestManager.java => ConnectOAuth2RequestFactory.java} (87%) diff --git a/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java b/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java index c496547eb..6895a7e86 100644 --- a/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java +++ b/openid-connect-client/src/main/java/org/mitre/oauth2/introspectingfilter/IntrospectingTokenService.java @@ -11,8 +11,9 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.StoredOAuth2Request; import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.util.LinkedMultiValueMap; @@ -79,17 +80,18 @@ public class IntrospectingTokenService implements ResourceServerTokenServices { return null; } - private OAuth2Request createAuthRequest(final JsonObject token) { + private StoredOAuth2Request createStoredRequest(final JsonObject token) { + clientId = token.get("client_id").getAsString(); + Set scopes = new HashSet(); + for (JsonElement e : token.get("scope").getAsJsonArray()) { + scopes.add(e.getAsString()); + } + Map parameters = new HashMap(); + parameters.put("client_id", clientId); + parameters.put("scope", OAuth2Utils.formatParameterList(scopes)); + StoredOAuth2Request storedRequest = new StoredOAuth2Request(parameters, clientId, null, true, scopes, null, null, null); + return storedRequest; - clientId = token.get("client_id").getAsString(); - Set scopes = new HashSet(); - for (JsonElement e : token.get("scope").getAsJsonArray()) { - scopes.add(e.getAsString()); - } - OAuth2Request authReq = new OAuth2Request(); - authReq.setScope(scopes); - authReq.setClientId(clientId); - return authReq; } // create a default authentication object with authority ROLE_API @@ -141,7 +143,7 @@ public class IntrospectingTokenService implements ResourceServerTokenServices { return false; } // create an OAuth2Authentication - OAuth2Authentication auth = new OAuth2Authentication(createAuthRequest(tokenResponse), createAuthentication(tokenResponse)); + OAuth2Authentication auth = new OAuth2Authentication(createStoredRequest(tokenResponse), createAuthentication(tokenResponse)); // create an OAuth2AccessToken OAuth2AccessToken token = createAccessToken(tokenResponse, accessToken); diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java index 363f2f4ab..23cb53a97 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/AuthorizationCodeEntity.java @@ -12,7 +12,7 @@ import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; -import org.springframework.security.oauth2.provider.code.AuthorizationRequestHolder; +import org.springframework.security.oauth2.provider.OAuth2Authentication; /** * Entity class for authorization codes @@ -31,7 +31,7 @@ public class AuthorizationCodeEntity { private String code; - private AuthorizationRequestHolder authorizationRequestHolder; + private OAuth2Authentication authentication; /** * Default constructor. @@ -46,9 +46,9 @@ public class AuthorizationCodeEntity { * @param code the authorization code * @param authRequest the AuthoriztionRequestHolder associated with the original code request */ - public AuthorizationCodeEntity(String code, AuthorizationRequestHolder authRequest) { + public AuthorizationCodeEntity(String code, OAuth2Authentication authRequest) { this.code = code; - this.authorizationRequestHolder = authRequest; + this.authentication = authRequest; } /** @@ -83,20 +83,20 @@ public class AuthorizationCodeEntity { } /** - * @return the authorizationRequestHolder + * @return the authentication */ @Lob @Basic(fetch=FetchType.EAGER) - @Column(name="authorization_request_holder") - public AuthorizationRequestHolder getAuthorizationRequestHolder() { - return authorizationRequestHolder; + @Column(name="authentication") + public OAuth2Authentication getAuthentication() { + return authentication; } /** - * @param authorizationRequestHolder the authorizationRequestHolder to set + * @param authentication the authentication to set */ - public void setAuthorizationRequestHolder(AuthorizationRequestHolder authorizationRequestHolder) { - this.authorizationRequestHolder = authorizationRequestHolder; + public void setAuthentication(OAuth2Authentication authentication) { + this.authentication = authentication; } } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java index bdd2e295d..63c6b2e8b 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java @@ -2,7 +2,7 @@ package org.mitre.oauth2.repository; import org.mitre.oauth2.model.AuthorizationCodeEntity; import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; -import org.springframework.security.oauth2.provider.code.AuthorizationRequestHolder; +import org.springframework.security.oauth2.provider.OAuth2Authentication; /** * Interface for saving and consuming OAuth2 authorization codes as AuthorizationCodeEntitys. @@ -27,6 +27,6 @@ public interface AuthorizationCodeRepository { * @return the authentication associated with the code * @throws InvalidGrantException if no AuthorizationCodeEntity is found with the given value */ - public AuthorizationRequestHolder consume(String code) throws InvalidGrantException; + public OAuth2Authentication consume(String code) throws InvalidGrantException; } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java index 13e1a4350..1f696c91a 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java @@ -11,7 +11,7 @@ import org.mitre.oauth2.model.AuthorizationCodeEntity; import org.mitre.oauth2.repository.AuthorizationCodeRepository; import org.mitre.util.jpa.JpaUtil; import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; -import org.springframework.security.oauth2.provider.code.AuthorizationRequestHolder; +import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -44,7 +44,7 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito */ @Override @Transactional - public AuthorizationRequestHolder consume(String code) throws InvalidGrantException { + public OAuth2Authentication consume(String code) throws InvalidGrantException { TypedQuery query = manager.createNamedQuery("AuthorizationCodeEntity.getByValue", AuthorizationCodeEntity.class); query.setParameter("code", code); @@ -55,7 +55,7 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code); } - AuthorizationRequestHolder authRequest = result.getAuthorizationRequestHolder(); + OAuth2Authentication authRequest = result.getAuthentication(); manager.remove(result); diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java index 7c2c0fbc6..8052e4e0a 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java @@ -8,8 +8,8 @@ import org.mitre.oauth2.repository.AuthorizationCodeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; +import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; -import org.springframework.security.oauth2.provider.code.AuthorizationRequestHolder; import org.springframework.stereotype.Service; /** @@ -35,7 +35,7 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS * @return the authorization code */ @Override - public String createAuthorizationCode(AuthorizationRequestHolder authentication) { + public String createAuthorizationCode(OAuth2Authentication authentication) { String code = generator.generate(); AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authentication); @@ -55,9 +55,9 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS * @throws InvalidGrantException, if an AuthorizationCodeEntity is not found with the given value */ @Override - public AuthorizationRequestHolder consumeAuthorizationCode(String code) throws InvalidGrantException { + public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException { - AuthorizationRequestHolder auth = repository.consume(code); + OAuth2Authentication auth = repository.consume(code); return auth; } 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 cf934b31d..dc190fa83 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 @@ -43,7 +43,8 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.StoredOAuth2Request; +import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.stereotype.Service; @@ -78,9 +79,9 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi @Override public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException { - if (authentication != null && authentication.getAuthorizationRequest() != null) { + if (authentication != null && authentication.getStoredRequest() != null) { // look up our client - OAuth2Request clientAuth = authentication.getAuthorizationRequest(); + StoredOAuth2Request clientAuth = authentication.getStoredRequest(); ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); @@ -151,7 +152,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi tokenRepository.saveAccessToken(token); //Add approved site reference, if any - OAuth2Request originalAuthRequest = authHolder.getAuthentication().getAuthorizationRequest(); + StoredOAuth2Request originalAuthRequest = authHolder.getAuthentication().getStoredRequest(); if (originalAuthRequest.getExtensionProperties().containsKey("approved_site")) { @@ -175,7 +176,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi } @Override - public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, OAuth2Request authRequest) throws AuthenticationException { + public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException { OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue); @@ -207,7 +208,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); // get the stored scopes from the authentication holder's authorization request; these are the scopes associated with the refresh token - Set refreshScopes = new HashSet(refreshToken.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getScope()); + Set refreshScopes = new HashSet(refreshToken.getAuthenticationHolder().getAuthentication().getStoredRequest().getScope()); Set scope = new HashSet(authRequest.getScope()); if (scope != null && !scope.isEmpty()) { diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java b/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java index 08d62476f..180d69090 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java @@ -10,14 +10,13 @@ import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.OAuth2AccessTokenEntity; import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.exceptions.InvalidScopeException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.token.AbstractTokenGranter; -import org.springframework.stereotype.Component; import com.google.common.collect.Sets; @@ -25,7 +24,7 @@ import com.google.common.collect.Sets; * @author jricher * */ -@Component("chainedTokenGranter") +//@Component("chainedTokenGranter") public class ChainedTokenGranter extends AbstractTokenGranter { private static final String grantType = "urn:ietf:params:oauth:grant_type:redelegate"; @@ -33,29 +32,31 @@ public class ChainedTokenGranter extends AbstractTokenGranter { // keep down-cast versions so we can get to the right queries private OAuth2TokenEntityService tokenServices; + + /** * @param tokenServices * @param clientDetailsService * @param grantType */ - @Autowired - public ChainedTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService) { - super(tokenServices, clientDetailsService, grantType); + //@Autowired + public ChainedTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) { + super(tokenServices, clientDetailsService, requestFactory, grantType); this.tokenServices = tokenServices; } - + /* (non-Javadoc) * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) */ @Override - protected OAuth2Authentication getOAuth2Authentication(OAuth2Request authorizationRequest) throws AuthenticationException, InvalidTokenException { + protected OAuth2Authentication getOAuth2Authentication(TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { // read and load up the existing token - String incomingTokenValue = authorizationRequest.getRequestParameters().get("token"); + String incomingTokenValue = tokenRequest.getRequestParameters().get("token"); OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); // check for scoping in the request, can't up-scope with a chained request Set approvedScopes = incomingToken.getScope(); - Set requestedScopes = authorizationRequest.getScope(); + Set requestedScopes = tokenRequest.getScope(); if (requestedScopes == null) { requestedScopes = new HashSet(); @@ -71,21 +72,19 @@ public class ChainedTokenGranter extends AbstractTokenGranter { // if our scopes are a valid subset of what's allowed, we can continue if (approvedScopes.containsAll(requestedScopes)) { - // build an appropriate auth request to hand to the token services layer - authorizationRequest.setApproved(true); if (requestedScopes.isEmpty()) { // if there are no scopes, inherit the original scopes from the token - authorizationRequest.setScope(approvedScopes); + tokenRequest.setScope(approvedScopes); } else { // if scopes were asked for, give only the subset of scopes requested // this allows safe downscoping - authorizationRequest.setScope(Sets.intersection(requestedScopes, approvedScopes)); + tokenRequest.setScope(Sets.intersection(requestedScopes, approvedScopes)); } // NOTE: don't revoke the existing access token // create a new access token - OAuth2Authentication authentication = new OAuth2Authentication(authorizationRequest, incomingToken.getAuthenticationHolder().getAuthentication().getUserAuthentication()); + OAuth2Authentication authentication = new OAuth2Authentication(getRequestFactory().createStoredOAuth2Request(tokenRequest), incomingToken.getAuthenticationHolder().getAuthentication().getUserAuthentication()); return authentication; diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java b/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java index 2c718aee7..1bb68734d 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/token/JwtAssertionTokenGranter.java @@ -17,7 +17,8 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; -import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.token.AbstractTokenGranter; import org.springframework.stereotype.Component; @@ -46,8 +47,8 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter { private ConfigurationPropertiesBean config; @Autowired - public JwtAssertionTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService) { - super(tokenServices, clientDetailsService, grantType); + public JwtAssertionTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) { + super(tokenServices, clientDetailsService, requestFactory, grantType); this.tokenServices = tokenServices; } @@ -55,9 +56,9 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter { * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) */ @Override - protected OAuth2AccessToken getAccessToken(OAuth2Request oAuthRequest) throws AuthenticationException, InvalidTokenException { + protected OAuth2AccessToken getAccessToken(TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { // read and load up the existing token - String incomingTokenValue = oAuthRequest.getRequestParameters().get("assertion"); + String incomingTokenValue = tokenRequest.getRequestParameters().get("assertion"); OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); ClientDetailsEntity client = incomingToken.getClient(); @@ -65,7 +66,7 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter { if (incomingToken.getScope().contains(OAuth2AccessTokenEntity.ID_TOKEN_SCOPE)) { - if (!client.getClientId().equals(oAuthRequest.getClientId())) { + if (!client.getClientId().equals(tokenRequest.getClientId())) { throw new InvalidClientException("Not the right client for this token"); } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java b/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java index dedf3437c..121a01f41 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/view/TokenIntrospectionView.java @@ -101,7 +101,7 @@ public class TokenIntrospectionView extends AbstractView { token.addProperty("subject", src.getAuthenticationHolder().getAuthentication().getName()); - token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getClientId()); + token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getStoredRequest().getClientId()); return token; } diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java index e176b39ca..eae313455 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java @@ -31,8 +31,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; +import org.springframework.security.oauth2.provider.AuthorizationRequest; import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; @@ -67,7 +67,7 @@ public class OAuthConfirmationController { @PreAuthorize("hasRole('ROLE_USER')") @RequestMapping("/oauth/confirm_access") - public ModelAndView confimAccess(Map model, @ModelAttribute("authorizationRequest") OAuth2Request clientAuth) { + public ModelAndView confimAccess(Map model, @ModelAttribute("authorizationRequest") AuthorizationRequest clientAuth) { //AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest"); diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java index 8d0f2ec63..84a2a88cd 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java @@ -28,7 +28,7 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.StoredOAuth2Request; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -86,7 +86,7 @@ public class RevocationEndpoint { // we've got a client acting on its own behalf, not an admin //ClientAuthentication clientAuth = (ClientAuthenticationToken) ((OAuth2Authentication) auth).getClientAuthentication(); - OAuth2Request clientAuth = ((OAuth2Authentication) principal).getAuthorizationRequest(); + StoredOAuth2Request clientAuth = ((OAuth2Authentication) principal).getStoredRequest(); if (refreshToken != null) { if (!refreshToken.getClient().getClientId().equals(clientAuth.getClientId())) { diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestManager.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestFactory.java similarity index 87% rename from openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestManager.java rename to openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestFactory.java index 11ce08597..922d70ff4 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestManager.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/ConnectOAuth2RequestFactory.java @@ -23,19 +23,19 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.common.util.OAuth2Utils; +import org.springframework.security.oauth2.provider.AuthorizationRequest; import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +import org.springframework.security.oauth2.provider.DefaultOAuth2RequestFactory; import org.springframework.stereotype.Component; import com.google.common.base.Strings; import com.nimbusds.jose.util.JSONObjectUtils; import com.nimbusds.jwt.SignedJWT; -@Component("oAuth2RequestManager") -public class ConnectOAuth2RequestManager implements OAuth2RequestFactory { +@Component("oAuth2RequestFactory") +public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { - private static Logger logger = LoggerFactory.getLogger(ConnectOAuth2RequestManager.class); + private static Logger logger = LoggerFactory.getLogger(ConnectOAuth2RequestFactory.class); @Autowired private NonceService nonceService; @@ -52,7 +52,8 @@ public class ConnectOAuth2RequestManager implements OAuth2RequestFactory { * @param clientDetailsService * @param nonceService */ - public ConnectOAuth2RequestManager(ClientDetailsEntityService clientDetailsService, NonceService nonceService) { + public ConnectOAuth2RequestFactory(ClientDetailsEntityService clientDetailsService, NonceService nonceService) { + super(clientDetailsService); this.clientDetailsService = clientDetailsService; this.nonceService = nonceService; } @@ -60,12 +61,12 @@ public class ConnectOAuth2RequestManager implements OAuth2RequestFactory { /** * Default empty constructor */ - public ConnectOAuth2RequestManager() { - + public ConnectOAuth2RequestFactory() { + super(null); } @Override - public OAuth2Request createOAuth2Request(Map inputParams) { + public AuthorizationRequest createAuthorizationRequest(Map inputParams) { Map parameters = processRequestObject(inputParams); @@ -78,12 +79,12 @@ public class ConnectOAuth2RequestManager implements OAuth2RequestFactory { String requestNonce = parameters.get("nonce"); - OAuth2Request request = new OAuth2Request(parameters, Collections. emptyMap(), - parameters.get(OAuth2Request.CLIENT_ID), - OAuth2Utils.parseParameterList(parameters.get(OAuth2Request.SCOPE)), null, - null, false, parameters.get(OAuth2Request.STATE), - parameters.get(OAuth2Request.REDIRECT_URI), - OAuth2Utils.parseParameterList(parameters.get(OAuth2Request.RESPONSE_TYPE))); + AuthorizationRequest request = new AuthorizationRequest(parameters, Collections. emptyMap(), + parameters.get(OAuth2Utils.CLIENT_ID), + OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)), null, + null, false, parameters.get(OAuth2Utils.STATE), + parameters.get(OAuth2Utils.REDIRECT_URI), + OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.RESPONSE_TYPE))); //Only process if the user is authenticated. If the user is not authenticated yet, this //code will be called a second time once the user is redirected from the login page back diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java index 7db97aff7..09aed7219 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java @@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.StoredOAuth2Request; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.stereotype.Service; @@ -62,7 +62,7 @@ public class ConnectTokenEnhancer implements TokenEnhancer { public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) accessToken; - OAuth2Request originalAuthRequest = authentication.getAuthorizationRequest(); + StoredOAuth2Request originalAuthRequest = authentication.getStoredRequest(); String clientId = originalAuthRequest.getClientId(); ClientDetailsEntity client = clientService.loadClientByClientId(clientId); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java index 3ec96c00d..0c28406ac 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java @@ -27,9 +27,9 @@ import org.mitre.openid.connect.service.ApprovedSiteService; import org.mitre.openid.connect.service.WhitelistedSiteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.provider.AuthorizationRequest; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; -import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; import org.springframework.stereotype.Component; @@ -66,17 +66,17 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { @Override - public boolean isApproved(OAuth2Request oAuthRequest, Authentication userAuthentication) { + public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { // if this request is already approved, pass that info through // (this flag may be set by updateBeforeApproval, which can also do funny things with scopes, etc) - if (oAuthRequest.isApproved()) { + if (authorizationRequest.isApproved()) { return true; } else { // if not, check to see if the user has approved it // TODO: make parameter name configurable? - boolean approved = Boolean.parseBoolean(oAuthRequest.getApprovalParameters().get("user_oauth_approval")); + boolean approved = Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval")); return userAuthentication.isAuthenticated() && approved; } @@ -89,19 +89,19 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { * * Otherwise the user will be directed to the approval page and can make their own decision. * - * @param oAuthRequest the incoming authorization request + * @param authorizationRequest the incoming authorization request * @param userAuthentication the Principal representing the currently-logged-in user * * @return the updated AuthorizationRequest */ @Override - public OAuth2Request checkForPreApproval(OAuth2Request oAuthRequest, Authentication userAuthentication) { + public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { //First, check database to see if the user identified by the userAuthentication has stored an approval decision //getName may not be filled in? TODO: investigate String userId = userAuthentication.getName(); - String clientId = oAuthRequest.getClientId(); + String clientId = authorizationRequest.getClientId(); //lookup ApprovedSites by userId and clientId boolean alreadyApproved = false; @@ -111,14 +111,14 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { if (!ap.isExpired()) { // if we find one that fits... - if (scopesMatch(oAuthRequest.getScope(), ap.getAllowedScopes())) { + if (scopesMatch(authorizationRequest.getScope(), ap.getAllowedScopes())) { //We have a match; update the access date on the AP entry and return true. ap.setAccessDate(new Date()); approvedSiteService.save(ap); - oAuthRequest.getExtensionProperties().put("approved_site", ap.getId()); - oAuthRequest.setApproved(true); + authorizationRequest.getExtensionProperties().put("approved_site", ap.getId()); + authorizationRequest.setApproved(true); alreadyApproved = true; } } @@ -126,37 +126,37 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { if (!alreadyApproved) { WhitelistedSite ws = whitelistedSiteService.getByClientId(clientId); - if (ws != null && scopesMatch(oAuthRequest.getScope(), ws.getAllowedScopes())) { + if (ws != null && scopesMatch(authorizationRequest.getScope(), ws.getAllowedScopes())) { //Create an approved site ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, null, ws.getAllowedScopes(), ws); - oAuthRequest.getExtensionProperties().put("approved_site", newSite.getId()); - oAuthRequest.setApproved(true); + authorizationRequest.getExtensionProperties().put("approved_site", newSite.getId()); + authorizationRequest.setApproved(true); } } - return oAuthRequest; + return authorizationRequest; } @Override - public OAuth2Request updateAfterApproval(OAuth2Request oAuthRequest, Authentication userAuthentication) { + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { String userId = userAuthentication.getName(); - String clientId = oAuthRequest.getClientId(); + String clientId = authorizationRequest.getClientId(); ClientDetails client = clientDetailsService.loadClientByClientId(clientId); // This must be re-parsed here because SECOAUTH forces us to call things in a strange order - boolean approved = Boolean.parseBoolean(oAuthRequest.getApprovalParameters().get("user_oauth_approval")); + boolean approved = Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval")); if (approved) { - oAuthRequest.setApproved(true); + authorizationRequest.setApproved(true); // process scopes from user input Set allowedScopes = Sets.newHashSet(); - Map approvalParams = oAuthRequest.getApprovalParameters(); + Map approvalParams = authorizationRequest.getApprovalParameters(); Set keys = approvalParams.keySet(); @@ -177,10 +177,10 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { // inject the user-allowed scopes into the auth request // TODO: for the moment this allows both upscoping and downscoping. - oAuthRequest.setScope(allowedScopes); + authorizationRequest.setScope(allowedScopes); //Only store an ApprovedSite if the user has checked "remember this decision": - String remember = oAuthRequest.getApprovalParameters().get("remember"); + String remember = authorizationRequest.getApprovalParameters().get("remember"); if (!Strings.isNullOrEmpty(remember) && !remember.equals("none")) { Date timeout = null; @@ -192,12 +192,12 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { } ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, timeout, allowedScopes, null); - oAuthRequest.getExtensionProperties().put("approved_site", newSite.getId()); + authorizationRequest.getExtensionProperties().put("approved_site", newSite.getId()); } } - return oAuthRequest; + return authorizationRequest; } /** 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 0cbeb7905..b3c1ead96 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 @@ -26,8 +26,8 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +import org.springframework.security.oauth2.provider.StoredOAuth2Request; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -173,7 +173,7 @@ public class ClientDynamicRegistrationEndpoint { ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - if (client != null && client.getClientId().equals(auth.getAuthorizationRequest().getClientId())) { + if (client != null && client.getClientId().equals(auth.getStoredRequest().getClientId())) { // we return the token that we got in @@ -189,7 +189,7 @@ public class ClientDynamicRegistrationEndpoint { } else { // client mismatch logger.error("readClientConfiguration failed, client ID mismatch: " - + clientId + " and " + auth.getAuthorizationRequest().getClientId() + " do not match."); + + clientId + " and " + auth.getStoredRequest().getClientId() + " do not match."); m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403 return "httpCodeView"; @@ -213,7 +213,7 @@ public class ClientDynamicRegistrationEndpoint { ClientDetailsEntity oldClient = clientService.loadClientByClientId(clientId); if (newClient != null && oldClient != null // we have an existing client and the new one parsed - && oldClient.getClientId().equals(auth.getAuthorizationRequest().getClientId()) // the client passed in the URI matches the one in the auth + && oldClient.getClientId().equals(auth.getStoredRequest().getClientId()) // the client passed in the URI matches the one in the auth && oldClient.getClientId().equals(newClient.getClientId()) // the client passed in the body matches the one in the URI ) { @@ -260,7 +260,7 @@ public class ClientDynamicRegistrationEndpoint { } else { // client mismatch logger.error("readClientConfiguration failed, client ID mismatch: " - + clientId + " and " + auth.getAuthorizationRequest().getClientId() + " do not match."); + + clientId + " and " + auth.getStoredRequest().getClientId() + " do not match."); m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403 return "httpCodeView"; @@ -280,7 +280,7 @@ public class ClientDynamicRegistrationEndpoint { ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - if (client != null && client.getClientId().equals(auth.getAuthorizationRequest().getClientId())) { + if (client != null && client.getClientId().equals(auth.getStoredRequest().getClientId())) { clientService.deleteClient(client); @@ -297,7 +297,7 @@ public class ClientDynamicRegistrationEndpoint { } else { // client mismatch logger.error("readClientConfiguration failed, client ID mismatch: " - + clientId + " and " + auth.getAuthorizationRequest().getClientId() + " do not match."); + + clientId + " and " + auth.getStoredRequest().getClientId() + " do not match."); m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403 return "httpCodeView"; @@ -470,10 +470,10 @@ public class ClientDynamicRegistrationEndpoint { Map authorizationParameters = Maps.newHashMap(); authorizationParameters.put("client_id", client.getClientId()); authorizationParameters.put("scope", OAuth2AccessTokenEntity.REGISTRATION_TOKEN_SCOPE); - OAuth2Request oAuthRequest = oAuth2RequestFactory.createOAuth2Request(authorizationParameters); - oAuthRequest.setApproved(true); - oAuthRequest.setAuthorities(Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT"))); - OAuth2Authentication authentication = new OAuth2Authentication(oAuthRequest, null); + StoredOAuth2Request storedRequest = new StoredOAuth2Request(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; } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java index d05499654..e5832c1d2 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java @@ -98,8 +98,8 @@ public class UserInfoEndpoint { if (p instanceof OAuth2Authentication) { OAuth2Authentication authentication = (OAuth2Authentication)p; - model.addAttribute("scope", authentication.getAuthorizationRequest().getScope()); - model.addAttribute("requestObject", authentication.getAuthorizationRequest().getRequestParameters().get("request")); + model.addAttribute("scope", authentication.getStoredRequest().getScope()); + model.addAttribute("requestObject", authentication.getStoredRequest().getRequestParameters().get("request")); } model.addAttribute("userInfo", userInfo); diff --git a/openid-connect-server/src/main/resources/db/tables/hsql_database_tables.sql b/openid-connect-server/src/main/resources/db/tables/hsql_database_tables.sql index b1230acc6..4b0a01a2d 100644 --- a/openid-connect-server/src/main/resources/db/tables/hsql_database_tables.sql +++ b/openid-connect-server/src/main/resources/db/tables/hsql_database_tables.sql @@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS client_authority ( CREATE TABLE IF NOT EXISTS authorization_code ( id BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, code VARCHAR(256), - authorization_request_holder LONGVARBINARY + authentication LONGVARBINARY ); CREATE TABLE IF NOT EXISTS client_grant_type ( diff --git a/openid-connect-server/src/main/resources/db/tables/mysql_database_tables.sql b/openid-connect-server/src/main/resources/db/tables/mysql_database_tables.sql index 747e45685..8d1716e7e 100644 --- a/openid-connect-server/src/main/resources/db/tables/mysql_database_tables.sql +++ b/openid-connect-server/src/main/resources/db/tables/mysql_database_tables.sql @@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS client_authority ( CREATE TABLE IF NOT EXISTS authorization_code ( id BIGINT AUTO_INCREMENT PRIMARY KEY, code VARCHAR(256), - authorization_request_holder LONGBLOB + authentication LONGBLOB ); CREATE TABLE IF NOT EXISTS client_grant_type ( diff --git a/openid-connect-server/src/main/webapp/WEB-INF/application-context.xml b/openid-connect-server/src/main/webapp/WEB-INF/application-context.xml index d57512926..ee1e69185 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/application-context.xml +++ b/openid-connect-server/src/main/webapp/WEB-INF/application-context.xml @@ -105,7 +105,7 @@ + + + + + + @@ -145,7 +151,7 @@ - + diff --git a/spring-security-oauth b/spring-security-oauth index 2b4beaf66..c377ba89f 160000 --- a/spring-security-oauth +++ b/spring-security-oauth @@ -1 +1 @@ -Subproject commit 2b4beaf663490388b0d485b81bc8f2cf8a586b6c +Subproject commit c377ba89fb066b40939459e4f192bb49487ec959