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;
+ }
}