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/07/29 16:36:34 UTC

cxf git commit: More work on the abstract jose support code

Repository: cxf
Updated Branches:
  refs/heads/master 9fc3be7e5 -> b32c5d0cb


More work on the abstract jose support code


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/b32c5d0c
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/b32c5d0c
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/b32c5d0c

Branch: refs/heads/master
Commit: b32c5d0cbf61ae599c33e401679066d92b8e2024
Parents: 9fc3be7
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Wed Jul 29 17:36:18 2015 +0300
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Wed Jul 29 17:36:18 2015 +0300

----------------------------------------------------------------------
 .../main/webapp/WEB-INF/applicationContext.xml  | 13 ++--
 .../jose/jwt/AbstractJoseJwtConsumer.java       |  9 ++-
 .../jose/jwt/AbstractJoseJwtProducer.java       |  2 +-
 .../oidc/rp/AbstractTokenValidator.java         | 74 +++-----------------
 .../cxf/rs/security/oidc/rp/IdTokenReader.java  |  2 +-
 .../oidc/rp/OidcClientCodeRequestFilter.java    |  7 +-
 .../cxf/rs/security/oidc/rp/UserInfoClient.java | 19 +++--
 7 files changed, 36 insertions(+), 90 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/b32c5d0c/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml b/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
index e099c28..08e0d23 100644
--- a/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
@@ -116,7 +116,8 @@
          <property name="clientCodeStateManager" ref="rpClientCodeStateManager"/>
          <property name="scopes" value="openid email profile https://www.googleapis.com/auth/bigquery.readonly"/>
          <property name="accessTokenServiceClient" ref="atServiceClient"/>
-         <property name="idTokenReader" ref="userInfoClient"/>
+         <property name="idTokenReader" ref="idTokenReader"/>
+         <property name="userInfoClient" ref="userInfoClient"/>
          <property name="consumer" ref="consumer"/>
          <property name="authorizationServiceUri" value="https://accounts.google.com/o/oauth2/auth"/>
          <property name="startUri" value="rp"/>
@@ -144,16 +145,12 @@
         </jaxrsclient:features>
      </jaxrsclient:client> 
      
-     <!-- The RP filter uses this client to read OIDC IdToken from OAuth2 access token and
-          request OIDC UserInfo. If OIDC IdToken only is required then registering 
-          org.apache.cxf.rs.security.oidc.rp.IdTokenReader is enough. 
-     --> 
-     <bean id="userInfoClient" class="org.apache.cxf.rs.security.oidc.rp.UserInfoClient">
-         <!-- these properties are needed to validate IdToken -->
+     <bean id="idTokenReader" class="org.apache.cxf.rs.security.oidc.rp.IdTokenReader">
          <property name="jwkSetClient" ref="jwkSetClient"/> 
          <property name="issuerId" value="accounts.google.com"/>
          <property name="clockOffset" value="10"/>
-         <!-- this one is needed to get OIDC UserInfo --> 
+     </bean>
+     <bean id="userInfoClient" class="org.apache.cxf.rs.security.oidc.rp.UserInfoClient">
          <property name="userInfoServiceClient" ref="userInfoServiceClient"/>
      </bean>
      

http://git-wip-us.apache.org/repos/asf/cxf/blob/b32c5d0c/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
index fc00c81..0708cac 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
@@ -27,7 +27,7 @@ import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
 
 public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer {
     private boolean jwsRequired = true;
-    private boolean jweRequired = true;
+    private boolean jweRequired;
     
     protected JwtToken getJwtToken(String wrappedJwtToken) {
         if (!isJwsRequired() && !isJweRequired()) {
@@ -42,14 +42,17 @@ public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer {
         } 
 
         JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(wrappedJwtToken);
-        JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(isJwsRequired());
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(jwt);
         if (!jwtConsumer.verifySignatureWith(theSigVerifier)) {
             throw new SecurityException("Invalid Signature");
         }
-        JwtToken jwt = jwtConsumer.getJwtToken(); 
         validateToken(jwt);
         return jwt; 
     }
+    protected JwsSignatureVerifier getInitializedSignatureVerifier(JwtToken jwt) {
+        return super.getInitializedSignatureVerifier(isJwsRequired());
+    }
     protected void validateToken(JwtToken jwt) {
     }
     public boolean isJwsRequired() {

http://git-wip-us.apache.org/repos/asf/cxf/blob/b32c5d0c/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java
index bd2e1da..6ec4b44 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java
@@ -28,7 +28,7 @@ import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 
 public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer {
     private boolean jwsRequired = true;
-    private boolean jweRequired = true;
+    private boolean jweRequired;
     
     protected String processJwt(JwtToken jwt) {
         if (!isJwsRequired() && !isJweRequired()) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/b32c5d0c/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
index 0b271e8..e79c4f0 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
@@ -21,48 +21,25 @@ package org.apache.cxf.rs.security.oidc.rp;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
-import org.apache.cxf.rs.security.jose.jwe.JweJwtCompactConsumer;
-import org.apache.cxf.rs.security.jose.jwe.JweUtils;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
 import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
-import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
 import org.apache.cxf.rs.security.jose.jws.JwsUtils;
+import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtConsumer;
 import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.cxf.rs.security.jose.jwt.JwtUtils;
 
-public abstract class AbstractTokenValidator {
+public abstract class AbstractTokenValidator extends AbstractJoseJwtConsumer {
     private static final String SELF_ISSUED_ISSUER = "https://self-issued.me";
-    private JweDecryptionProvider jweDecryptor;
-    private JwsSignatureVerifier jwsVerifier;
     private String issuerId;
     private int issuedAtRange;
     private int clockOffset;
     private WebClient jwkSetClient;
     private boolean supportSelfIssuedProvider;
     private ConcurrentHashMap<String, JsonWebKey> keyMap = new ConcurrentHashMap<String, JsonWebKey>(); 
-    protected JwtToken getJwtToken(String wrappedJwtToken, boolean jweOnly) {
-        if (wrappedJwtToken == null) {
-            throw new SecurityException("ID Token is missing");
-        }
-        JweDecryptionProvider theJweDecryptor = getInitializedDecryptionProvider(jweOnly);
-        if (theJweDecryptor != null) {
-            if (jweOnly) {
-                return new JweJwtCompactConsumer(wrappedJwtToken).decryptWith(jweDecryptor);    
-            }
-            wrappedJwtToken = jweDecryptor.decrypt(wrappedJwtToken).getContentText();
-        }
-
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(wrappedJwtToken);
-        JwtToken jwt = jwtConsumer.getJwtToken(); 
-        JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(jwt);
-        return validateToken(jwtConsumer, jwt, theSigVerifier);
         
-    }
-    
     protected void validateJwtClaims(JwtClaims claims, String clientId, boolean validateClaimsAlways) {
         // validate the issuer
         String issuer = claims.getIssuer();
@@ -90,21 +67,6 @@ public abstract class AbstractTokenValidator {
         }
     }
     
-    
-    protected JwtToken validateToken(JwsJwtCompactConsumer consumer, JwtToken jwt, JwsSignatureVerifier jws) {
-        if (!consumer.verifySignatureWith(jws)) {
-            throw new SecurityException("Invalid Signature");
-        }
-        return jwt;
-    }
-    public void setJweDecryptor(JweDecryptionProvider jweDecryptor) {
-        this.jweDecryptor = jweDecryptor;
-    }
-
-    public void setJwsVerifier(JwsSignatureVerifier theJwsVerifier) {
-        this.jwsVerifier = theJwsVerifier;
-    }
-
     public void setIssuerId(String issuerId) {
         this.issuerId = issuerId;
     }
@@ -117,21 +79,8 @@ public abstract class AbstractTokenValidator {
         this.issuedAtRange = issuedAtRange;
     }
 
-    protected JweDecryptionProvider getInitializedDecryptionProvider(boolean jweOnly) {
-        if (jweDecryptor != null) {
-            return jweDecryptor;    
-        } 
-        return JweUtils.loadDecryptionProvider(jweOnly);
-    }
+    @Override
     protected JwsSignatureVerifier getInitializedSignatureVerifier(JwtToken jwt) {
-        if (jwsVerifier != null) {
-            return jwsVerifier;    
-        } 
-        JwsSignatureVerifier theJwsVerifier = JwsUtils.loadSignatureVerifier(false);
-        if (theJwsVerifier != null) {
-            return theJwsVerifier;
-        }
-        
         JsonWebKey key = null;
         if (supportSelfIssuedProvider && SELF_ISSUED_ISSUER.equals(jwt.getClaim("issuer"))) {
             String publicKeyJson = (String)jwt.getClaim("sub_jwk");
@@ -148,10 +97,7 @@ public abstract class AbstractTokenValidator {
         } else {
             String keyId = jwt.getHeaders().getKeyId();
             key = keyId != null ? keyMap.get(keyId) : null;
-            if (key == null) {
-                if (jwkSetClient == null) {
-                    throw new SecurityException("Provider Jwk Set Client is not available");
-                }
+            if (key == null && jwkSetClient != null) {
                 JsonWebKeys keys = jwkSetClient.get(JsonWebKeys.class);
                 if (keyId != null) {
                     key = keys.getKey(keyId);
@@ -160,13 +106,13 @@ public abstract class AbstractTokenValidator {
                 }
                 keyMap.putAll(keys.getKeyIdMap());
             }
-            if (key == null) {
-                throw new SecurityException("JWK key with the key id: \"" + keyId + "\" is not available");
-            }
         }
-        
-        theJwsVerifier = JwsUtils.getSignatureVerifier(key);
-        
+        JwsSignatureVerifier theJwsVerifier = null;
+        if (key != null) {
+            theJwsVerifier = JwsUtils.getSignatureVerifier(key);
+        } else {
+            theJwsVerifier = super.getInitializedSignatureVerifier(jwt);
+        }
         if (theJwsVerifier == null) {
             throw new SecurityException("JWS Verifier is not available");
         }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b32c5d0c/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java
index ff633a1..63161d5 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java
@@ -40,7 +40,7 @@ public class IdTokenReader extends AbstractTokenValidator {
         return jwt;
     }
     public JwtToken getIdJwtToken(String idJwtToken, String clientId) {
-        JwtToken jwt = getJwtToken(idJwtToken, false);
+        JwtToken jwt = getJwtToken(idJwtToken);
         validateJwtClaims(jwt.getClaims(), clientId, true);
         return jwt;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b32c5d0c/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
index 6406e3b..aa34cf1 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
@@ -41,6 +41,7 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter {
     private static final String MAX_AGE_PARAMETER = "max_age";
     private static final List<String> PROMPTS = Arrays.asList("none", "consent", "login", "select_account");
     private IdTokenReader idTokenReader;
+    private UserInfoClient userInfoClient;
     private List<String> authenticationContextRef;
     private String promptLogin;
     private Long maxAgeOffset;
@@ -64,8 +65,7 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter {
             validateIdToken(idToken, state);
             
             ctx.setIdToken(idToken);
-            if (idTokenReader instanceof UserInfoClient) {
-                UserInfoClient userInfoClient = (UserInfoClient)idTokenReader;
+            if (userInfoClient != null) {
                 ctx.setUserInfo(userInfoClient.getUserInfo(at, ctx.getIdToken()));
             }
             rc.setSecurityContext(new OidcSecurityContext(ctx));
@@ -106,6 +106,9 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter {
     public void setIdTokenReader(IdTokenReader idTokenReader) {
         this.idTokenReader = idTokenReader;
     }
+    public void setUserInfoClient(UserInfoClient userInfoClient) {
+        this.userInfoClient = userInfoClient; 
+    }
     
     @Override
     protected void checkSecurityContextStart(ContainerRequestContext rc) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/b32c5d0c/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java
index f1d0998..058867c 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java
@@ -27,17 +27,14 @@ 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;
 
-public class UserInfoClient extends IdTokenReader {
-    private boolean encryptedOnly;
+public class UserInfoClient extends AbstractTokenValidator {
     private boolean sendTokenAsFormParameter;
     private WebClient profileClient;
+    private boolean getUserInfoFromJwt;
     public UserInfo getUserInfo(ClientAccessToken at, IdToken idToken) {
-        return getUserInfo(at, idToken, false);
-    }
-    public UserInfo getUserInfo(ClientAccessToken at, IdToken idToken, boolean asJwt) {
         if (!sendTokenAsFormParameter) {
             OAuthClientUtils.setAuthorizationHeader(profileClient, at);
-            if (asJwt) {
+            if (getUserInfoFromJwt) {
                 String jwt = profileClient.get(String.class);
                 return getUserInfoFromJwt(jwt, idToken);
             } else {
@@ -47,7 +44,7 @@ public class UserInfoClient extends IdTokenReader {
             }
         } else {
             Form form = new Form().param("access_token", at.getTokenKey());
-            if (asJwt) {
+            if (getUserInfoFromJwt) {
                 String jwt = profileClient.form(form).readEntity(String.class);
                 return getUserInfoFromJwt(jwt, idToken);
             } else {
@@ -67,7 +64,7 @@ public class UserInfoClient extends IdTokenReader {
         return profile;
     }
     public JwtToken getUserInfoJwt(String profileJwtToken) {
-        return getJwtToken(profileJwtToken, encryptedOnly);
+        return getJwtToken(profileJwtToken);
     }
     public void validateUserInfo(UserInfo profile, IdToken idToken) {
         validateJwtClaims(profile, idToken.getAudience(), false);
@@ -76,14 +73,14 @@ public class UserInfoClient extends IdTokenReader {
             throw new SecurityException("Invalid subject");
         }
     }
-    public void setEncryptedOnly(boolean encryptedOnly) {
-        this.encryptedOnly = encryptedOnly;
-    }
     public void setUserInfoServiceClient(WebClient client) {
         this.profileClient = client;
     }
     public void setSendTokenAsFormParameter(boolean sendTokenAsFormParameter) {
         this.sendTokenAsFormParameter = sendTokenAsFormParameter;
     }
+    public void setGetUserInfoFromJwt(boolean getUserInfoFromJwt) {
+        this.getUserInfoFromJwt = getUserInfoFromJwt;
+    }
     
 }