From d71d76c54e7e6b30fbf39b97a1ea12924b818494 Mon Sep 17 00:00:00 2001 From: Amanda Anganes Date: Thu, 9 Feb 2012 14:33:03 -0500 Subject: [PATCH] Partially implemented ConnectAuthCodeTokenGranter.java. Builds & deploys, but not tested. --- ...DefaultJwtSigningAndValidationService.java | 46 +++++ .../token/ConnectAuthCodeTokenGranter.java | 174 +++++++++++++++++- .../WEB-INF/spring/application-context.xml | 15 +- 3 files changed, 225 insertions(+), 10 deletions(-) create mode 100644 server/src/main/java/org/mitre/jwt/service/impl/DefaultJwtSigningAndValidationService.java diff --git a/server/src/main/java/org/mitre/jwt/service/impl/DefaultJwtSigningAndValidationService.java b/server/src/main/java/org/mitre/jwt/service/impl/DefaultJwtSigningAndValidationService.java new file mode 100644 index 000000000..60b6bd71a --- /dev/null +++ b/server/src/main/java/org/mitre/jwt/service/impl/DefaultJwtSigningAndValidationService.java @@ -0,0 +1,46 @@ +package org.mitre.jwt.service.impl; + +import java.security.PublicKey; +import java.util.List; + +import org.mitre.jwt.model.Jwt; +import org.mitre.jwt.service.JwtSigningAndValidationService; +import org.springframework.stereotype.Service; + +/** + * THIS IS A STUB + * + * TODO: Implement + * + * @author AANGANES + * + */ +@Service +public class DefaultJwtSigningAndValidationService implements + JwtSigningAndValidationService { + + @Override + public List getAllPublicKeys() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean validateSignature(String jwtString) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean validateIssuedJwt(Jwt jwt) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isJwtExpired(Jwt jwt) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java b/server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java index 969d89c7d..c9f41014e 100644 --- a/server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java +++ b/server/src/main/java/org/mitre/openid/connect/token/ConnectAuthCodeTokenGranter.java @@ -3,28 +3,184 @@ */ package org.mitre.openid.connect.token; +import java.util.Map; +import java.util.Set; + +import org.mitre.oauth2.model.OAuth2AccessTokenEntity; +import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService; +import org.mitre.openid.connect.model.IdToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidClientException; +import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; +import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; +import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.security.oauth2.provider.ClientCredentialsChecker; import org.springframework.security.oauth2.provider.ClientDetailsService; -import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; -import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.TokenGranter; +import org.springframework.security.oauth2.provider.code.AuthorizationRequestHolder; +import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices; +import org.springframework.stereotype.Component; /** + * AccessToken granter for Authorization Code flow. + * + * Note: does this need to be able to grant straight OAuth2.0 Access Tokens as + * well as Connect Access Tokens? + * + * * @author AANGANES - * + * */ -public class ConnectAuthCodeTokenGranter extends AuthorizationCodeTokenGranter { +@Component +public class ConnectAuthCodeTokenGranter implements TokenGranter { + private static final String GRANT_TYPE = "authorization_code"; + + @Autowired + private JdbcAuthorizationCodeServices authorizationCodeServices; + + @Autowired + private ClientCredentialsChecker clientCredentialsChecker; + + @Autowired + private DefaultOAuth2ProviderTokenService tokenServices; + + /** + * Default empty constructor + */ + public ConnectAuthCodeTokenGranter() { + } + + /** + * Constructor for unit tests + * * @param tokenServices * @param authorizationCodeServices * @param clientDetailsService */ public ConnectAuthCodeTokenGranter( - AuthorizationServerTokenServices tokenServices, - AuthorizationCodeServices authorizationCodeServices, + DefaultOAuth2ProviderTokenService tokenServices, + JdbcAuthorizationCodeServices authorizationCodeServices, ClientDetailsService clientDetailsService) { - super(tokenServices, authorizationCodeServices, clientDetailsService); - // TODO Auto-generated constructor stub + + setTokenServices(tokenServices); + setAuthorizationCodeServices(authorizationCodeServices); + setClientCredentialsChecker(new ClientCredentialsChecker(clientDetailsService)); + + } + + + /** + * Grant an OpenID Connect Access Token + * + * @param grantType + * @param parameters + * @param clientId + * @param scope + */ + @Override + public OAuth2AccessToken grant(String grantType, + Map parameters, String clientId, Set scope) { + + if (!GRANT_TYPE.equals(grantType)) { + return null; + } + + String authorizationCode = parameters.get("code"); + String redirectUri = parameters.get("redirect_uri"); + + if (authorizationCode == null) { + throw new OAuth2Exception("An authorization code must be supplied."); + } + + AuthorizationRequestHolder storedAuth = authorizationCodeServices.consumeAuthorizationCode(authorizationCode); + if (storedAuth == null) { + throw new InvalidGrantException("Invalid authorization code: " + authorizationCode); + } + + AuthorizationRequest unconfirmedAuthorizationRequest = storedAuth.getAuthenticationRequest(); + if (unconfirmedAuthorizationRequest.getRedirectUri() != null + && !unconfirmedAuthorizationRequest.getRedirectUri().equals(redirectUri)) { + throw new RedirectMismatchException("Redirect URI mismatch."); + } + + if (clientId != null && !clientId.equals(unconfirmedAuthorizationRequest.getClientId())) { + // just a sanity check. + throw new InvalidClientException("Client ID mismatch"); + } + + // Secret is not required in the authorization request, so it won't be available + // in the unconfirmedAuthorizationCodeAuth. We do want to check that a secret is provided + // in the new request, but that happens elsewhere. + + // Similarly scopes are not required in the authorization request, so we don't make a comparison here, just + // enforce validity through the ClientCredentialsChecker + AuthorizationRequest authorizationRequest = clientCredentialsChecker.validateCredentials(grantType, clientId, + unconfirmedAuthorizationRequest.getScope()); + if (authorizationRequest == null) { + return null; + } + + Authentication userAuth = storedAuth.getUserAuthentication(); + + OAuth2AccessTokenEntity token = tokenServices.createAccessToken(new OAuth2Authentication(authorizationRequest, userAuth)); + + IdToken idToken = new IdToken(); + + //TODO: build IdToken + + //TODO: insert IdToken into OAuth2AccessTokenEntity + + return token; } + /** + * @return the authorizationCodeServices + */ + public JdbcAuthorizationCodeServices getAuthorizationCodeServices() { + return authorizationCodeServices; + } + + /** + * @param authorizationCodeServices the authorizationCodeServices to set + */ + public void setAuthorizationCodeServices(JdbcAuthorizationCodeServices authorizationCodeServices) { + this.authorizationCodeServices = authorizationCodeServices; + } + + /** + * @return the clientCredentialsChecker + */ + public ClientCredentialsChecker getClientCredentialsChecker() { + return clientCredentialsChecker; + } + + /** + * @param clientCredentialsChecker the clientCredentialsChecker to set + */ + public void setClientCredentialsChecker(ClientCredentialsChecker clientCredentialsChecker) { + this.clientCredentialsChecker = clientCredentialsChecker; + } + + /** + * @return the tokenServices + */ + public DefaultOAuth2ProviderTokenService getTokenServices() { + return tokenServices; + } + + /** + * @param tokenServices the tokenServices to set + */ + public void setTokenServices(DefaultOAuth2ProviderTokenService tokenServices) { + this.tokenServices = tokenServices; + } + + + } diff --git a/server/src/main/webapp/WEB-INF/spring/application-context.xml b/server/src/main/webapp/WEB-INF/spring/application-context.xml index dbe8cd518..ca35f16c2 100644 --- a/server/src/main/webapp/WEB-INF/spring/application-context.xml +++ b/server/src/main/webapp/WEB-INF/spring/application-context.xml @@ -22,6 +22,19 @@ + + + + + + + + + + + + + @@ -53,6 +66,6 @@ - +