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