Authorization Grant flow works up to serializing the returned Access Token. Justin is investigating serialization problems.
parent
d94eb338ee
commit
ebe72412fe
|
@ -23,9 +23,13 @@ import javax.persistence.Table;
|
||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.Transient;
|
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.jwt.model.Jwt;
|
||||||
import org.mitre.openid.connect.model.IdToken;
|
import org.mitre.openid.connect.model.IdToken;
|
||||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
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.common.OAuth2RefreshToken;
|
||||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
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.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")
|
@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 class OAuth2AccessTokenEntity extends OAuth2AccessToken {
|
||||||
|
|
||||||
public static String ID_TOKEN = "id_token";
|
public static String ID_TOKEN = "id_token";
|
||||||
|
|
|
@ -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.InvalidClientException;
|
||||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Transactional
|
||||||
public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService {
|
public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -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.AuthorizationRequest;
|
||||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ import com.google.common.collect.Sets;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@Transactional
|
||||||
public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityService {
|
public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityService {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(DefaultOAuth2ProviderTokenService.class);
|
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());
|
throw new InvalidClientException("Client not found: " + clientAuth.getClientId());
|
||||||
}
|
}
|
||||||
|
|
||||||
OAuth2AccessTokenEntity token = accessTokenFactory.createNewAccessToken();
|
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();//accessTokenFactory.createNewAccessToken();
|
||||||
|
|
||||||
// attach the client
|
// attach the client
|
||||||
token.setClient(client);
|
token.setClient(client);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||||
|
import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
||||||
import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService;
|
import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService;
|
||||||
import org.mitre.openid.connect.model.IdToken;
|
import org.mitre.openid.connect.model.IdToken;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -46,9 +47,11 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ClientCredentialsChecker clientCredentialsChecker;
|
private ClientCredentialsChecker clientCredentialsChecker;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: Do we need to modify/update this?
|
//TODO: Do we need to modify/update this?
|
||||||
@Autowired
|
@Autowired
|
||||||
private DefaultOAuth2ProviderTokenService tokenServices;
|
private OAuth2TokenEntityService tokenServices;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IdTokenGeneratorService idTokenService;
|
private IdTokenGeneratorService idTokenService;
|
||||||
|
@ -131,7 +134,10 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
|
|
||||||
Authentication userAuth = storedAuth.getUserAuthentication();
|
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
|
* 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
|
//TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have
|
||||||
//See github issue #1
|
//See github issue #1
|
||||||
IdToken idToken = idTokenService.generateIdToken(userId, "http://id.mitre.org/openidconnect");
|
IdToken idToken = idTokenService.generateIdToken(userId, "http://id.mitre.org/openidconnect");
|
||||||
|
idToken.getClaims().setAudience(clientId);
|
||||||
|
|
||||||
token.setIdToken(idToken);
|
token.setIdToken(idToken);
|
||||||
}
|
}
|
||||||
|
@ -180,20 +187,12 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
|
||||||
this.clientCredentialsChecker = clientCredentialsChecker;
|
this.clientCredentialsChecker = clientCredentialsChecker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public OAuth2TokenEntityService getTokenServices() {
|
||||||
* @return the tokenServices
|
|
||||||
*/
|
|
||||||
public DefaultOAuth2ProviderTokenService getTokenServices() {
|
|
||||||
return tokenServices;
|
return tokenServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setTokenServices(OAuth2TokenEntityService tokenServices) {
|
||||||
* @param tokenServices the tokenServices to set
|
|
||||||
*/
|
|
||||||
public void setTokenServices(DefaultOAuth2ProviderTokenService tokenServices) {
|
|
||||||
this.tokenServices = tokenServices;
|
this.tokenServices = tokenServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,14 @@
|
||||||
<persistence-unit name="openidPersistenceUnit" transaction-type="RESOURCE_LOCAL">
|
<persistence-unit name="openidPersistenceUnit" transaction-type="RESOURCE_LOCAL">
|
||||||
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
||||||
<class>org.mitre.oauth2.model.ClientDetailsEntity</class>
|
<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-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -5,17 +5,21 @@
|
||||||
xmlns:context="http://www.springframework.org/schema/context"
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
xmlns:security="http://www.springframework.org/schema/security"
|
xmlns:security="http://www.springframework.org/schema/security"
|
||||||
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
|
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/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/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/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
|
||||||
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.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 -->
|
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
|
||||||
|
|
||||||
<!-- Enables the Spring MVC @Controller programming model -->
|
<!-- Enables the Spring MVC @Controller programming model -->
|
||||||
<annotation-driven />
|
<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 -->
|
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
|
||||||
<resources mapping="/resources/**" location="/resources/" />
|
<resources mapping="/resources/**" location="/resources/" />
|
||||||
|
|
||||||
|
|
|
@ -19,27 +19,43 @@
|
||||||
|
|
||||||
<import resource="data-context.xml" />
|
<import resource="data-context.xml" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<security:global-method-security pre-post-annotations="enabled" proxy-target-class="true" authentication-manager-ref="springSecurityAuthenticationManager"/>
|
<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">
|
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
|
||||||
<security:intercept-url pattern="/oauth/authorize**" access="hasRole('ROLE_USER')"/>
|
xmlns="http://www.springframework.org/schema/security">
|
||||||
<!-- <security:intercept-url pattern="/openidconnect/token**" access="hasRole('ROLE_USER')"/> -->
|
<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:intercept-url pattern="/**" access="permitAll"/>
|
||||||
</security:http>
|
</security:http>
|
||||||
|
|
||||||
<!-- <security:http pattern="/oauth/**" use-expressions="true" auto-config="true" authentication-manager-ref="springSecurityAuthenticationManager"> -->
|
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
|
||||||
<!-- <security:intercept-url pattern="/oauth/**" access="hasRole('ROLE_USER')"/> -->
|
<property name="realmName" value="openidconnect" />
|
||||||
<!-- </security:http> -->
|
</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"/> -->
|
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
|
||||||
|
<property name="authenticationManager" ref="clientAuthenticationManager" />
|
||||||
<!-- <security:http pattern="/openidconnect/auth" security="none" authentication-manager-ref="springSecurityAuthenticationManager"/> -->
|
</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">
|
<bean id="clientCredentialsChecker" class="org.springframework.security.oauth2.provider.ClientCredentialsChecker">
|
||||||
<constructor-arg>
|
<constructor-arg>
|
||||||
|
@ -49,14 +65,14 @@
|
||||||
|
|
||||||
<bean id="authCodeServices" class="org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices"/>
|
<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:authentication-provider>
|
||||||
<security:user-service id="userDetailsService">
|
<security:user-service id="userDetailsService">
|
||||||
<security:user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
|
<security:user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
|
||||||
<security:user name="bob" password="bobspassword" authorities="ROLE_USER" />
|
<security:user name="bob" password="bobspassword" authorities="ROLE_USER" />
|
||||||
</security:user-service>
|
</security:user-service>
|
||||||
</security:authentication-provider>
|
</security:authentication-provider>
|
||||||
</security:authentication-manager>
|
</security:authentication-manager>
|
||||||
|
|
||||||
<tx:annotation-driven transaction-manager="transactionManager" />
|
<tx:annotation-driven transaction-manager="transactionManager" />
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue