Authorization Grant flow works up to serializing the returned Access Token. Justin is investigating serialization problems.

pull/59/head
Amanda Anganes 2012-03-21 16:44:16 -04:00
parent d94eb338ee
commit ebe72412fe
8 changed files with 127 additions and 31 deletions

View File

@ -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";

View File

@ -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

View File

@ -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);

View File

@ -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<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
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;
}
}

View File

@ -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;
}
}

View File

@ -6,5 +6,14 @@
<persistence-unit name="openidPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>org.mitre.oauth2.model.ClientDetailsEntity</class>
<class>org.mitre.oauth2.model.OAuth2AccessTokenEntity</class>
<class>org.mitre.oauth2.model.OAuth2RefreshTokenEntity</class>
<class>org.mitre.openid.connect.model.Address</class>
<class>org.mitre.openid.connect.model.ApprovedSite</class>
<class>org.mitre.openid.connect.model.Event</class>
<class>org.mitre.openid.connect.model.IdToken</class>
<class>org.mitre.openid.connect.model.IdTokenClaims</class>
<class>org.mitre.openid.connect.model.UserInfo</class>
<class>org.mitre.openid.connect.model.WhitelistedSite</class>
</persistence-unit>
</persistence>

View File

@ -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">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

View File

@ -19,27 +19,43 @@
<import resource="data-context.xml" />
<security:global-method-security pre-post-annotations="enabled" proxy-target-class="true" authentication-manager-ref="springSecurityAuthenticationManager"/>
<security:http use-expressions="true" auto-config="true" authentication-manager-ref="springSecurityAuthenticationManager">
<security:intercept-url pattern="/oauth/authorize**" access="hasRole('ROLE_USER')"/>
<!-- <security:intercept-url pattern="/openidconnect/token**" access="hasRole('ROLE_USER')"/> -->
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<security:http use-expressions="true" auto-config="true" pattern="/oauth/authorize" authentication-manager-ref="springSecurityAuthenticationManager">
<security:intercept-url pattern="/oauth/authorize" access="hasRole('ROLE_USER')"/>
<!-- intercept-url with access=permitall means a permissive (lets everything through) filter will be applied -->
</security:http>
<!-- means no filter will be applied -->
<security:http auto-config="true" pattern="/openidconnect/token" authentication-manager-ref="springSecurityAuthenticationManager" security="none"/>
<security:http auto-config="true" use-expressions="true" authentication-manager-ref="springSecurityAuthenticationManager">
<security:intercept-url pattern="/**" access="permitAll"/>
</security:http>
<!-- <security:http pattern="/oauth/**" use-expressions="true" auto-config="true" authentication-manager-ref="springSecurityAuthenticationManager"> -->
<!-- <security:intercept-url pattern="/oauth/**" access="hasRole('ROLE_USER')"/> -->
<!-- </security:http> -->
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="openidconnect" />
</bean>
<!-- <security:http pattern="/resources/**" security="none" authentication-manager-ref="springSecurityAuthenticationManager"/> -->
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<!-- <security:http pattern="/oauth/authorize" security="none" authentication-manager-ref="springSecurityAuthenticationManager"/> -->
<!-- <security:http pattern="/openidconnect/auth" security="none" authentication-manager-ref="springSecurityAuthenticationManager"/> -->
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<!-- <security:http pattern="/**" security="none" authentication-manager-ref="springSecurityAuthenticationManager"/> -->
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientUserDetailsService" />
</authentication-manager>
<bean id="clientCredentialsChecker" class="org.springframework.security.oauth2.provider.ClientCredentialsChecker">
<constructor-arg>
@ -49,14 +65,14 @@
<bean id="authCodeServices" class="org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices"/>
<security:authentication-manager id="springSecurityAuthenticationManager">
<security:authentication-manager alias="springSecurityAuthenticationManager">
<security:authentication-provider>
<security:user-service id="userDetailsService">
<security:user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<security:user name="bob" password="bobspassword" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</security:authentication-manager>
<tx:annotation-driven transaction-manager="transactionManager" />