From ebe72412febbf06b2eeba2885f7859d8741ff906 Mon Sep 17 00:00:00 2001 From: Amanda Anganes Date: Wed, 21 Mar 2012 16:44:16 -0400 Subject: [PATCH] Authorization Grant flow works up to serializing the returned Access Token. Justin is investigating serialization problems. --- .../oauth2/model/OAuth2AccessTokenEntity.java | 6 ++ ...faultOAuth2ClientDetailsEntityService.java | 2 + .../DefaultOAuth2ProviderTokenService.java | 4 +- .../service/ClientUserDetailsService.java | 58 +++++++++++++++++++ .../token/ConnectAuthCodeTokenGranter.java | 23 ++++---- .../main/resources/META-INF/persistence.xml | 9 +++ .../spring/appServlet/servlet-context.xml | 10 +++- .../WEB-INF/spring/application-context.xml | 46 ++++++++++----- 8 files changed, 127 insertions(+), 31 deletions(-) create mode 100644 openid-connect-server/src/main/java/org/mitre/openid/connect/service/ClientUserDetailsService.java diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java index 64ac252a2..f59f7fa07 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java @@ -23,9 +23,13 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.Transient; +import org.codehaus.jackson.map.annotate.JsonDeserialize; +import org.codehaus.jackson.map.annotate.JsonSerialize; import org.mitre.jwt.model.Jwt; import org.mitre.openid.connect.model.IdToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessTokenDeserializer; +import org.springframework.security.oauth2.common.OAuth2AccessTokenSerializer; import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; @@ -40,6 +44,8 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; @NamedQuery(name = "OAuth2AccessTokenEntity.getByClient", query = "select a from OAuth2AccessTokenEntity a where a.client = :client"), @NamedQuery(name = "OAuth2AccessTokenEntity.getExpired", query = "select a from OAuth2AccessTokenEntity a where a.expiration is not null and a.expiration < current_timestamp") }) +@JsonSerialize(using = OAuth2AccessTokenSerializer.class) +@JsonDeserialize(using = OAuth2AccessTokenDeserializer.class) public class OAuth2AccessTokenEntity extends OAuth2AccessToken { public static String ID_TOKEN = "id_token"; diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java index 785d7ed9f..e761e0ca3 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java @@ -13,10 +13,12 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.google.common.base.Strings; @Service +@Transactional public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService { @Autowired 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 d641afd4c..c8c73e406 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 @@ -27,6 +27,7 @@ import org.springframework.security.oauth2.common.exceptions.InvalidTokenExcepti import org.springframework.security.oauth2.provider.AuthorizationRequest; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.google.common.collect.Sets; @@ -36,6 +37,7 @@ import com.google.common.collect.Sets; * */ @Service +@Transactional public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityService { private static Logger logger = LoggerFactory.getLogger(DefaultOAuth2ProviderTokenService.class); @@ -65,7 +67,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi throw new InvalidClientException("Client not found: " + clientAuth.getClientId()); } - OAuth2AccessTokenEntity token = accessTokenFactory.createNewAccessToken(); + OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();//accessTokenFactory.createNewAccessToken(); // attach the client token.setClient(client); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/ClientUserDetailsService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/ClientUserDetailsService.java new file mode 100644 index 000000000..a2b27ebc4 --- /dev/null +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/ClientUserDetailsService.java @@ -0,0 +1,58 @@ +package org.mitre.openid.connect.service; + +import java.util.ArrayList; +import java.util.List; + +import org.mitre.oauth2.model.ClientDetailsEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.stereotype.Service; + +/** + * Shim layer to convert a ClientDetails service into a UserDetails service + * + * @author AANGANES + * + */ +@Service +public class ClientUserDetailsService implements UserDetailsService { + + @Autowired + ClientDetailsService clientDetailsService; + + @Override + public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException, DataAccessException { + + ClientDetails client = clientDetailsService.loadClientByClientId(clientId); + + + String password = client.getClientSecret(); + boolean enabled = true; + boolean accountNonExpired = true; + boolean credentialsNonExpired = true; + boolean accountNonLocked = true; + List authorities = new ArrayList(); + GrantedAuthority roleClient = new SimpleGrantedAuthority("ROLE_CLIENT"); + authorities.add(roleClient); + + return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); + + } + + public ClientDetailsService getClientDetailsService() { + return clientDetailsService; + } + + public void setClientDetailsService(ClientDetailsService clientDetailsService) { + this.clientDetailsService = clientDetailsService; + } + +} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java index 6c9e238b3..1734f27f6 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Set; import org.mitre.oauth2.model.OAuth2AccessTokenEntity; +import org.mitre.oauth2.service.OAuth2TokenEntityService; import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService; import org.mitre.openid.connect.model.IdToken; import org.springframework.beans.factory.annotation.Autowired; @@ -46,9 +47,11 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter { @Autowired private ClientCredentialsChecker clientCredentialsChecker; + + //TODO: Do we need to modify/update this? @Autowired - private DefaultOAuth2ProviderTokenService tokenServices; + private OAuth2TokenEntityService tokenServices; @Autowired private IdTokenGeneratorService idTokenService; @@ -131,7 +134,10 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter { Authentication userAuth = storedAuth.getUserAuthentication(); - OAuth2AccessTokenEntity token = tokenServices.createAccessToken(new OAuth2Authentication(authorizationRequest, userAuth)); + //TODO: should not need cast + OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) tokenServices.createAccessToken(new OAuth2Authentication(authorizationRequest, userAuth)); + + //set audience, auth time, issuer /** * Authorization request scope MUST include "openid", but access token request @@ -145,6 +151,7 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter { //TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have //See github issue #1 IdToken idToken = idTokenService.generateIdToken(userId, "http://id.mitre.org/openidconnect"); + idToken.getClaims().setAudience(clientId); token.setIdToken(idToken); } @@ -180,20 +187,12 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter { this.clientCredentialsChecker = clientCredentialsChecker; } - /** - * @return the tokenServices - */ - public DefaultOAuth2ProviderTokenService getTokenServices() { + public OAuth2TokenEntityService getTokenServices() { return tokenServices; } - /** - * @param tokenServices the tokenServices to set - */ - public void setTokenServices(DefaultOAuth2ProviderTokenService tokenServices) { + public void setTokenServices(OAuth2TokenEntityService tokenServices) { this.tokenServices = tokenServices; } - - } diff --git a/openid-connect-server/src/main/resources/META-INF/persistence.xml b/openid-connect-server/src/main/resources/META-INF/persistence.xml index f35ab6bfe..c58431c5e 100644 --- a/openid-connect-server/src/main/resources/META-INF/persistence.xml +++ b/openid-connect-server/src/main/resources/META-INF/persistence.xml @@ -6,5 +6,14 @@ org.eclipse.persistence.jpa.PersistenceProvider org.mitre.oauth2.model.ClientDetailsEntity + org.mitre.oauth2.model.OAuth2AccessTokenEntity + org.mitre.oauth2.model.OAuth2RefreshTokenEntity + org.mitre.openid.connect.model.Address + org.mitre.openid.connect.model.ApprovedSite + org.mitre.openid.connect.model.Event + org.mitre.openid.connect.model.IdToken + org.mitre.openid.connect.model.IdTokenClaims + org.mitre.openid.connect.model.UserInfo + org.mitre.openid.connect.model.WhitelistedSite diff --git a/openid-connect-server/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml b/openid-connect-server/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml index 70caaa644..1b84d77de 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml +++ b/openid-connect-server/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml @@ -5,17 +5,21 @@ xmlns:context="http://www.springframework.org/schema/context" xmlns:security="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2" - xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd + xmlns:tx="http://www.springframework.org/schema/tx" + xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd + http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd - http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd"> + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + + diff --git a/openid-connect-server/src/main/webapp/WEB-INF/spring/application-context.xml b/openid-connect-server/src/main/webapp/WEB-INF/spring/application-context.xml index 9712ab91f..95e027b4a 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/spring/application-context.xml +++ b/openid-connect-server/src/main/webapp/WEB-INF/spring/application-context.xml @@ -19,27 +19,43 @@ - - - - - + + + + + + + + + + + + + + + + + + - - - + + + - + - - - + + + - + + + @@ -49,14 +65,14 @@ - + - +