Having code hash reported in Oifc Hybrid authorization endpoint too
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/c29c334e Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/c29c334e Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/c29c334e Branch: refs/heads/master-jaxrs-2.1 Commit: c29c334e40cd9c6c846e265993eeda953a4f1d67 Parents: 25a4220 Author: Sergey Beryozkin <sberyoz...@gmail.com> Authored: Fri May 20 12:10:21 2016 +0100 Committer: Sergey Beryozkin <sberyoz...@gmail.com> Committed: Fri May 20 12:10:21 2016 +0100 ---------------------------------------------------------------------- .../oidc/idp/IdTokenResponseFilter.java | 17 +++++++-- .../rs/security/oidc/idp/OidcHybridService.java | 13 ++++--- .../security/oidc/idp/OidcImplicitService.java | 37 +++++++++++++++----- 3 files changed, 51 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/c29c334e/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenResponseFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenResponseFilter.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenResponseFilter.java index c05a9ce..74daf71 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenResponseFilter.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenResponseFilter.java @@ -89,6 +89,7 @@ public class IdTokenResponseFilter extends OAuthServerJoseJwtProducer implements && (rType.equals(OidcUtils.CODE_ID_TOKEN_AT_RESPONSE_TYPE) || rType.equals(OidcUtils.CODE_ID_TOKEN_RESPONSE_TYPE)); + Message m = JAXRSUtils.getCurrentMessage(); if (atHashRequired || cHashRequired) { Properties props = JwsUtils.loadSignatureOutProperties(false); SignatureAlgorithm sigAlgo = null; @@ -103,12 +104,22 @@ public class IdTokenResponseFilter extends OAuthServerJoseJwtProducer implements idToken.setAccessTokenHash(atHash); } if (cHashRequired) { - String cHash = OidcUtils.calculateAuthorizationCodeHash(st.getGrantCode(), sigAlgo); - idToken.setAuthorizationCodeHash(cHash); + // c_hash can be returned from either Authorization or Token endpoints + String code; + if (st.getGrantCode() != null) { + // This is a token endpoint, the code has been exchanged for a token + code = st.getGrantCode(); + } else { + // Authorization endpoint: hybrid flow, implicit part + code = (String)m.getExchange().get(OAuthConstants.AUTHORIZATION_CODE_VALUE); + } + if (code != null) { + idToken.setAuthorizationCodeHash(OidcUtils.calculateAuthorizationCodeHash(code, sigAlgo)); + } } } } - Message m = JAXRSUtils.getCurrentMessage(); + if (m != null && m.getExchange().containsKey(OAuthConstants.NONCE)) { idToken.setNonce((String)m.getExchange().get(OAuthConstants.NONCE)); } else if (st.getNonce() != null) { http://git-wip-us.apache.org/repos/asf/cxf/blob/c29c334e/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcHybridService.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcHybridService.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcHybridService.java index 2d93a5c..a77a0e4 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcHybridService.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcHybridService.java @@ -26,6 +26,7 @@ import java.util.Set; import javax.ws.rs.Path; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.OAuthRedirectionState; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; @@ -71,13 +72,17 @@ public class OidcHybridService extends OidcImplicitService { List<String> approvedScope, UserSubject userSubject, ServerAccessToken preAuthorizedToken) { + String code = null; + if (state.getResponseType() != null && state.getResponseType().startsWith(OAuthConstants.CODE_RESPONSE_TYPE)) { + code = codeService.getGrantCode(state, client, requestedScope, + approvedScope, userSubject, preAuthorizedToken); + JAXRSUtils.getCurrentMessage().getExchange().put(OAuthConstants.AUTHORIZATION_CODE_VALUE, code); + } + StringBuilder sb = super.prepareGrant(state, client, requestedScope, approvedScope, userSubject, preAuthorizedToken); - if (state.getResponseType() != null && state.getResponseType().startsWith(OAuthConstants.CODE_RESPONSE_TYPE)) { - String code = codeService.getGrantCode(state, client, requestedScope, - approvedScope, userSubject, preAuthorizedToken); - + if (code != null) { sb.append("&"); sb.append(OAuthConstants.AUTHORIZATION_CODE_VALUE).append("=").append(code); } http://git-wip-us.apache.org/repos/asf/cxf/blob/c29c334e/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcImplicitService.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcImplicitService.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcImplicitService.java index 60d1773..558dfd8 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcImplicitService.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/OidcImplicitService.java @@ -21,12 +21,15 @@ package org.apache.cxf.rs.security.oidc.idp; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Properties; import java.util.Set; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.cxf.rs.security.jose.jwt.JoseJwtProducer; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; +import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; +import org.apache.cxf.rs.security.jose.jws.JwsUtils; import org.apache.cxf.rs.security.jose.jwt.JwtToken; import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration; import org.apache.cxf.rs.security.oauth2.common.Client; @@ -35,16 +38,18 @@ import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; import org.apache.cxf.rs.security.oauth2.common.OAuthRedirectionState; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; import org.apache.cxf.rs.security.oauth2.common.UserSubject; +import org.apache.cxf.rs.security.oauth2.provider.OAuthJoseJwtProducer; import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; import org.apache.cxf.rs.security.oauth2.services.ImplicitGrantService; import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; +import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; import org.apache.cxf.rs.security.oidc.common.IdToken; import org.apache.cxf.rs.security.oidc.utils.OidcUtils; public class OidcImplicitService extends ImplicitGrantService { private boolean skipAuthorizationWithOidcScope; - private JoseJwtProducer idTokenHandler; + private OAuthJoseJwtProducer idTokenHandler; private IdTokenProvider idTokenProvider; public OidcImplicitService() { @@ -118,15 +123,13 @@ public class OidcImplicitService extends ImplicitGrantService { return subject.getProperties().get(OidcUtils.ID_TOKEN); } else if (idTokenProvider != null) { IdToken idToken = idTokenProvider.getIdToken(state.getClientId(), subject, scopes); - idToken.setNonce(state.getNonce()); - return processIdToken(idToken); + return processIdToken(state, idToken); } else if (subject instanceof OidcUserSubject) { OidcUserSubject sub = (OidcUserSubject)subject; IdToken idToken = new IdToken(sub.getIdToken()); idToken.setAudience(state.getClientId()); idToken.setAuthorizedParty(state.getClientId()); - idToken.setNonce(state.getNonce()); - return processIdToken(idToken); + return processIdToken(state, idToken); } else { return null; } @@ -152,12 +155,28 @@ public class OidcImplicitService extends ImplicitGrantService { return reg; } - protected String processIdToken(IdToken idToken) { - JoseJwtProducer processor = idTokenHandler == null ? new JoseJwtProducer() : idTokenHandler; + protected String processIdToken(OAuthRedirectionState state, IdToken idToken) { + OAuthJoseJwtProducer processor = idTokenHandler == null ? new OAuthJoseJwtProducer() : idTokenHandler; + + String code = + (String)JAXRSUtils.getCurrentMessage().getExchange().get(OAuthConstants.AUTHORIZATION_CODE_VALUE); + if (code != null) { + // this service is invoked as part of the hybrid flow + Properties props = JwsUtils.loadSignatureOutProperties(false); + SignatureAlgorithm sigAlgo = null; + if (processor.isSignWithClientSecret()) { + sigAlgo = OAuthUtils.getClientSecretSignatureAlgorithm(props); + } else { + sigAlgo = JwsUtils.getSignatureAlgorithm(props, SignatureAlgorithm.RS256); + } + idToken.setAuthorizationCodeHash(OidcUtils.calculateAuthorizationCodeHash(code, sigAlgo)); + } + + idToken.setNonce(state.getNonce()); return processor.processJwt(new JwtToken(idToken)); } - public void setIdTokenJoseHandler(JoseJwtProducer idTokenJoseHandler) { + public void setIdTokenJoseHandler(OAuthJoseJwtProducer idTokenJoseHandler) { this.idTokenHandler = idTokenJoseHandler; } public void setIdTokenProvider(IdTokenProvider idTokenProvider) {