You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2015/12/08 15:08:38 UTC
cxf git commit: Prototyping the code for setting an access token hash
in id_token
Repository: cxf
Updated Branches:
refs/heads/master a21976635 -> 5ca5bd90e
Prototyping the code for setting an access token hash in id_token
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/5ca5bd90
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/5ca5bd90
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/5ca5bd90
Branch: refs/heads/master
Commit: 5ca5bd90e9dae52019559918b408d8b0991b2764
Parents: a219766
Author: Sergey Beryozkin <sb...@gmail.com>
Authored: Tue Dec 8 14:08:19 2015 +0000
Committer: Sergey Beryozkin <sb...@gmail.com>
Committed: Tue Dec 8 14:08:19 2015 +0000
----------------------------------------------------------------------
.../cxf/rs/security/oauth2/common/Client.java | 22 +++++++++--
.../rs/security/oauth2/utils/OAuthUtils.java | 41 +++++++++++++-------
.../cxf/rs/security/oidc/common/IdToken.java | 17 +++++++-
.../cxf/rs/security/oidc/common/UserInfo.java | 3 +-
.../oidc/idp/IdTokenResponseFilter.java | 28 +++++++++++--
.../cxf/rs/security/oidc/utils/OidcUtils.java | 20 +++++++---
6 files changed, 104 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ca5bd90/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java
index 4f1b395..bc5c756 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java
@@ -50,7 +50,8 @@ public class Client implements Serializable {
private Map<String, String> properties = new HashMap<String, String>();
private UserSubject subject;
private UserSubject resourceOwnerSubject;
-
+ private boolean registeredAt;
+
public Client() {
}
@@ -64,10 +65,17 @@ public class Client implements Serializable {
public Client(String clientId,
String clientSecret,
boolean isConfidential,
- String applicationName,
- String applicationWebUri) {
+ String applicationName) {
this(clientId, clientSecret, isConfidential);
this.applicationName = applicationName;
+ }
+
+ public Client(String clientId,
+ String clientSecret,
+ boolean isConfidential,
+ String applicationName,
+ String applicationWebUri) {
+ this(clientId, clientSecret, isConfidential, applicationName);
this.applicationWebUri = applicationWebUri;
}
@@ -330,4 +338,12 @@ public class Client implements Serializable {
public void setClientIpAddress(String clientIpAddress) {
this.clientIpAddress = clientIpAddress;
}
+
+ public boolean isRegisteredAt() {
+ return registeredAt;
+ }
+
+ public void setRegisteredAt(boolean registeredAt) {
+ this.registeredAt = registeredAt;
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ca5bd90/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
index 5e8ed8a..0db2313 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
@@ -35,6 +35,7 @@ import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.model.URITemplate;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.jose.common.JoseConstants;
import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
@@ -268,37 +269,51 @@ public final class OAuthUtils {
}
public static JwsSignatureProvider getClientSecretSignatureProvider(String clientSecret) {
- return JwsUtils.getHmacSignatureProvider(clientSecret, getClientSecretSignatureAlgorithm());
+ Properties sigProps = JwsUtils.loadSignatureOutProperties(false);
+ return JwsUtils.getHmacSignatureProvider(clientSecret,
+ getClientSecretSignatureAlgorithm(sigProps));
}
public static JwsSignatureVerifier getClientSecretSignatureVerifier(String clientSecret) {
- return JwsUtils.getHmacSignatureVerifier(clientSecret, getClientSecretSignatureAlgorithm());
+ Properties sigProps = JwsUtils.loadSignatureOutProperties(false);
+ return JwsUtils.getHmacSignatureVerifier(clientSecret,
+ getClientSecretSignatureAlgorithm(sigProps));
}
public static JweDecryptionProvider getClientSecretDecryptionProvider(String clientSecret) {
+ Properties props = JweUtils.loadEncryptionInProperties(false);
byte[] key = StringUtils.toBytesUTF8(clientSecret);
- return JweUtils.getDirectKeyJweDecryption(key, getClientSecretContentAlgorithm());
+ return JweUtils.getDirectKeyJweDecryption(key, getClientSecretContentAlgorithm(props));
}
public static JweEncryptionProvider getClientSecretEncryptionProvider(String clientSecret) {
+ Properties props = JweUtils.loadEncryptionInProperties(false);
byte[] key = StringUtils.toBytesUTF8(clientSecret);
- return JweUtils.getDirectKeyJweEncryption(key, getClientSecretContentAlgorithm());
+ return JweUtils.getDirectKeyJweEncryption(key, getClientSecretContentAlgorithm(props));
}
- private static ContentAlgorithm getClientSecretContentAlgorithm() {
- Properties props = JweUtils.loadEncryptionInProperties(false);
- ContentAlgorithm ctAlgo = ContentAlgorithm.getAlgorithm(
- props.getProperty(OAuthConstants.CLIENT_SECRET_CONTENT_ENCRYPTION_ALGORITHM));
+ private static ContentAlgorithm getClientSecretContentAlgorithm(Properties props) {
+ String ctAlgoProp = props.getProperty(OAuthConstants.CLIENT_SECRET_CONTENT_ENCRYPTION_ALGORITHM);
+ if (ctAlgoProp == null) {
+ ctAlgoProp = props.getProperty(JoseConstants.RSSEC_ENCRYPTION_CONTENT_ALGORITHM);
+ }
+ ContentAlgorithm ctAlgo = ContentAlgorithm.getAlgorithm(ctAlgoProp);
ctAlgo = ctAlgo != null ? ctAlgo : ContentAlgorithm.A128GCM;
return ctAlgo;
}
- private static SignatureAlgorithm getClientSecretSignatureAlgorithm() {
- Properties sigProps = JwsUtils.loadSignatureOutProperties(false);
- SignatureAlgorithm sigAlgo = SignatureAlgorithm.getAlgorithm(
- sigProps.getProperty(OAuthConstants.CLIENT_SECRET_SIGNATURE_ALGORITHM));
+ public static SignatureAlgorithm getClientSecretSignatureAlgorithm(Properties sigProps) {
+
+ String clientSecretSigProp = sigProps.getProperty(OAuthConstants.CLIENT_SECRET_SIGNATURE_ALGORITHM);
+ if (clientSecretSigProp == null) {
+ String sigProp = sigProps.getProperty(JoseConstants.RSSEC_SIGNATURE_ALGORITHM);
+ if (AlgorithmUtils.isHmacSign(sigProp)) {
+ clientSecretSigProp = sigProp;
+ }
+ }
+ SignatureAlgorithm sigAlgo = SignatureAlgorithm.getAlgorithm(clientSecretSigProp);
sigAlgo = sigAlgo != null ? sigAlgo : SignatureAlgorithm.HS256;
if (!AlgorithmUtils.isHmacSign(sigAlgo)) {
- // Must be HS-based for the symmetric signature
+ // Must be HS-based for the symmetric signature
throw new OAuthServiceException(OAuthConstants.SERVER_ERROR);
} else {
return sigAlgo;
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ca5bd90/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/IdToken.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/IdToken.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/IdToken.java
index 63dfca3..6687e8b 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/IdToken.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/IdToken.java
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.rs.security.oidc.common;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -31,6 +32,8 @@ public class IdToken extends AbstractUserInfo {
public static final String ACR_CLAIM = "acr";
public static final String AZP_CLAIM = "azp";
public static final String AMR_CLAIM = "amr";
+ public static final String ACCESS_TOKEN_HASH_CLAIM = "at_hash";
+ public static final String AUTH_CODE_HASH_CLAIM = "c_hash";
public IdToken() {
}
@@ -40,7 +43,7 @@ public class IdToken extends AbstractUserInfo {
}
public IdToken(Map<String, Object> claims) {
- super(claims);
+ super(new LinkedHashMap<String, Object>(claims));
}
public void setAuthenticationTime(Long time) {
setProperty(AUTH_TIME_CLAIM, time);
@@ -72,5 +75,17 @@ public class IdToken extends AbstractUserInfo {
public String getAuthorizedParty() {
return (String)getProperty(AZP_CLAIM);
}
+ public void setAccessTokenHash(String at) {
+ setProperty(ACCESS_TOKEN_HASH_CLAIM, at);
+ }
+ public String getAccessTokenHash() {
+ return (String)getProperty(ACCESS_TOKEN_HASH_CLAIM);
+ }
+ public void setAuthCodeHash(String at) {
+ setProperty(AUTH_CODE_HASH_CLAIM, at);
+ }
+ public String getAuthCodeHash() {
+ return (String)getProperty(AUTH_CODE_HASH_CLAIM);
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ca5bd90/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/UserInfo.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/UserInfo.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/UserInfo.java
index f8da67a..1ac2986 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/UserInfo.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/common/UserInfo.java
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.rs.security.oidc.common;
+import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
@@ -29,6 +30,6 @@ public class UserInfo extends AbstractUserInfo {
this(claims.asMap());
}
public UserInfo(Map<String, Object> claims) {
- super(claims);
+ super(new LinkedHashMap<String, Object>(claims));
}
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ca5bd90/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 0d10d4e..0a19d8e 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
@@ -18,11 +18,16 @@
*/
package org.apache.cxf.rs.security.oidc.idp;
+import java.util.Properties;
+
+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.ClientAccessToken;
import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
import org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthServerJoseJwtProducer;
import org.apache.cxf.rs.security.oauth2.provider.AccessTokenResponseFilter;
+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;
@@ -39,18 +44,35 @@ public class IdTokenResponseFilter extends AbstractOAuthServerJoseJwtProducer im
}
private String getProcessedIdToken(ServerAccessToken st) {
if (userInfoProvider != null) {
- IdToken token =
+ IdToken idToken =
userInfoProvider.getIdToken(st.getClient().getClientId(), st.getSubject(), st.getScopes());
- return super.processJwt(new JwtToken(token), st.getClient());
+ setAtHash(idToken, st);
+ return super.processJwt(new JwtToken(idToken), st.getClient());
} else if (st.getSubject().getProperties().containsKey(OidcUtils.ID_TOKEN)) {
return st.getSubject().getProperties().get(OidcUtils.ID_TOKEN);
} else if (st.getSubject() instanceof OidcUserSubject) {
OidcUserSubject sub = (OidcUserSubject)st.getSubject();
- return super.processJwt(new JwtToken(sub.getIdToken()), st.getClient());
+ IdToken idToken = new IdToken(sub.getIdToken());
+ setAtHash(idToken, st);
+ return super.processJwt(new JwtToken(idToken), st.getClient());
} else {
return null;
}
}
+ private void setAtHash(IdToken idToken, ServerAccessToken st) {
+ Properties props = JwsUtils.loadSignatureOutProperties(false);
+ SignatureAlgorithm sigAlgo = null;
+ if (super.isSignWithClientSecret()) {
+ sigAlgo = OAuthUtils.getClientSecretSignatureAlgorithm(props);
+ } else {
+ sigAlgo = JwsUtils.getSignatureAlgorithm(props, SignatureAlgorithm.RS256);
+ }
+ if (sigAlgo != SignatureAlgorithm.NONE) {
+ String atHash = OidcUtils.calculateAccessTokenHash(st.getTokenKey(), sigAlgo);
+ idToken.setAccessTokenHash(atHash);
+ }
+
+ }
public void setUserInfoProvider(UserInfoProvider userInfoProvider) {
this.userInfoProvider = userInfoProvider;
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5ca5bd90/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java
index 42837fd..1e42454 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java
@@ -26,8 +26,10 @@ import java.util.Map;
import org.apache.cxf.common.util.Base64UrlUtility;
import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
+import org.apache.cxf.rs.security.oidc.common.IdToken;
import org.apache.cxf.rs.security.oidc.common.UserInfo;
import org.apache.cxf.rt.security.crypto.MessageDigestUtils;
@@ -94,8 +96,8 @@ public final class OidcUtils {
public static void validateAccessTokenHash(ClientAccessToken at, JwtToken jwt, boolean required) {
if (required) {
validateHash(at.getTokenKey(),
- (String)jwt.getClaims().getClaim("at_hash"),
- jwt.getJwsHeaders().getAlgorithm());
+ (String)jwt.getClaims().getClaim(IdToken.ACCESS_TOKEN_HASH_CLAIM),
+ jwt.getJwsHeaders().getSignatureAlgorithm());
}
}
public static void validateCodeHash(String code, JwtToken jwt) {
@@ -104,17 +106,23 @@ public final class OidcUtils {
public static void validateCodeHash(String code, JwtToken jwt, boolean required) {
if (required) {
validateHash(code,
- (String)jwt.getClaims().getClaim("c_hash"),
- jwt.getJwsHeaders().getAlgorithm());
+ (String)jwt.getClaims().getClaim(IdToken.AUTH_CODE_HASH_CLAIM),
+ jwt.getJwsHeaders().getSignatureAlgorithm());
}
}
- private static void validateHash(String value, String theHash, String joseAlgo) {
+ private static void validateHash(String value, String theHash, SignatureAlgorithm joseAlgo) {
String hash = calculateHash(value, joseAlgo);
if (!hash.equals(theHash)) {
throw new SecurityException("Invalid hash");
}
}
- public static String calculateHash(String value, String joseAlgo) {
+ public static String calculateAccessTokenHash(String value, SignatureAlgorithm joseAlgo) {
+ return calculateHash(value, joseAlgo);
+ }
+ public static String calculateAuthorizationCodeHash(String value, SignatureAlgorithm joseAlgo) {
+ return calculateHash(value, joseAlgo);
+ }
+ public static String calculateHash(String value, SignatureAlgorithm joseAlgo) {
//TODO: map from the JOSE alg to a signature alg,
// for example, RS256 -> SHA-256
// and calculate the chunk size based on the algo key size