Skip to content

Commit 8d2db70

Browse files
committed
Require c_hash for the hybrid case
1 parent 3d6f726 commit 8d2db70

3 files changed

Lines changed: 18 additions & 1 deletion

File tree

rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenResponseFilter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public void process(ClientAccessToken ct, ServerAccessToken st) {
5656
if (ct.getApprovedScope() == null || !ct.getApprovedScope().contains(OidcUtils.OPENID_SCOPE)) {
5757
return;
5858
}
59+
if (st.getResponseType() != null) {
60+
ct.getParameters().put(OAuthConstants.RESPONSE_TYPE, st.getResponseType());
61+
}
5962
String idToken = getProcessedIdToken(st);
6063
if (idToken != null) {
6164
ct.getParameters().put(OidcUtils.ID_TOKEN, idToken);

rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
2222
import org.apache.cxf.rs.security.oauth2.client.Consumer;
2323
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
24+
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
2425
import org.apache.cxf.rs.security.oidc.common.IdToken;
2526
import org.apache.cxf.rs.security.oidc.utils.OidcUtils;
2627

@@ -44,7 +45,11 @@ public JwtToken getIdJwtToken(ClientAccessToken at, String code, Consumer client
4445
String idJwtToken = at.getParameters().get(OidcUtils.ID_TOKEN);
4546
JwtToken jwt = getIdJwtToken(idJwtToken, client);
4647
OidcUtils.validateAccessTokenHash(at, jwt, requireAtHash);
47-
OidcUtils.validateCodeHash(code, jwt, requireCodeHash);
48+
if (code != null) {
49+
// The spec requires c_hash to be present in the id_token for hybrid flows,
50+
// but we allow it to be optional for token endpoint id_tokens
51+
OidcUtils.validateCodeHash(code, jwt, requireCodeHash || isHybridFlow(at));
52+
}
4853
return jwt;
4954
}
5055
public JwtToken getIdJwtToken(ClientAccessToken at, Consumer client) {
@@ -55,6 +60,13 @@ public JwtToken getIdJwtToken(String idJwtToken, Consumer client) {
5560
validateJwtClaims(jwt.getClaims(), client.getClientId(), true);
5661
return jwt;
5762
}
63+
64+
private boolean isHybridFlow(ClientAccessToken at) {
65+
String responseType = at.getParameters().get(OAuthConstants.RESPONSE_TYPE);
66+
return OidcUtils.CODE_ID_TOKEN_RESPONSE_TYPE.equals(responseType)
67+
|| OidcUtils.CODE_ID_TOKEN_AT_RESPONSE_TYPE.equals(responseType);
68+
}
69+
5870
private IdToken getIdTokenFromJwt(JwtToken jwt) {
5971
return new IdToken(jwt.getClaims().asMap());
6072
}

systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oidc/OIDCFlowTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,8 @@ public void testHybridCodeIdToken() throws Exception {
672672
OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code);
673673
assertNotNull(accessToken.getTokenKey());
674674
assertTrue(accessToken.getApprovedScope().contains("openid"));
675+
assertEquals(OidcUtils.CODE_ID_TOKEN_RESPONSE_TYPE,
676+
accessToken.getParameters().get(OAuthConstants.RESPONSE_TYPE));
675677

676678
// Check id_token from the token endpoint
677679
idToken = accessToken.getParameters().get("id_token");

0 commit comments

Comments
 (0)