You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2016/02/29 18:15:35 UTC
cxf-fediz git commit: Get keys from a remote URI to validate IdTokens
Repository: cxf-fediz
Updated Branches:
refs/heads/master 2dd2567fe -> c1d860563
Get keys from a remote URI to validate IdTokens
Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/c1d86056
Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/c1d86056
Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/c1d86056
Branch: refs/heads/master
Commit: c1d860563a1a8c0b6128f523db7a57884d278044
Parents: 2dd2567
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Mon Feb 29 17:15:14 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Mon Feb 29 17:15:14 2016 +0000
----------------------------------------------------------------------
.../TrustedIdpOIDCProtocolHandler.java | 75 ++++++++++++++++----
1 file changed, 62 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/c1d86056/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
index 0a25c54..9075012 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
@@ -55,7 +55,11 @@ import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxrs.client.ClientConfiguration;
import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.rs.security.jose.common.JoseConstants;
+import org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider;
import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
+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.jws.JwsJwtCompactConsumer;
import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
@@ -116,6 +120,11 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
*/
public static final String SCOPE = "scope";
+ /**
+ * The URI from which to retrieve the JSON Web Keys to validate the signed IdToken.
+ */
+ public static final String JWKS_URI = "jwks.uri";
+
public static final String PROTOCOL = "openid-connect-1.0";
private static final Logger LOG = LoggerFactory.getLogger(TrustedIdpOIDCProtocolHandler.class);
@@ -143,7 +152,7 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
String scope = getProperty(trustedIdp, SCOPE);
if (scope != null) {
scope = scope.trim();
- if (!scope.startsWith("openid")) {
+ if (!scope.contains("openid")) {
scope = "openid " + scope;
}
}
@@ -234,12 +243,6 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
}
try {
- X509Certificate validatingCert = getCertificate(trustedIdp.getCertificate());
- if (validatingCert == null) {
- LOG.warn("No X.509 Certificate configured for signature validation");
- return null;
- }
-
String whr = (String) WebUtils.getAttributeFromFlowScope(context,
FederationConstants.PARAM_HOME_REALM);
if (whr == null) {
@@ -265,12 +268,7 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
}
}
- // Validate the Signature
- String sigAlgo = getProperty(trustedIdp, SIGNATURE_ALGORITHM);
- if (sigAlgo == null || sigAlgo.isEmpty()) {
- sigAlgo = "RS256";
- }
- if (!jwtConsumer.verifySignatureWith(validatingCert, SignatureAlgorithm.getAlgorithm(sigAlgo))) {
+ if (!validateSignature(trustedIdp, jwtConsumer)) {
LOG.warn("Signature does not validate");
return null;
}
@@ -335,6 +333,57 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
JwtUtils.validateTokenClaims(jwt.getClaims(), 300, 0, false);
}
+ private boolean validateSignature(TrustedIdp trustedIdp, JwsJwtCompactConsumer jwtConsumer)
+ throws CertificateException, WSSecurityException, Base64DecodingException,
+ ProcessingException, IOException {
+
+ // Validate the Signature
+ String sigAlgo = getProperty(trustedIdp, SIGNATURE_ALGORITHM);
+ if (sigAlgo == null || sigAlgo.isEmpty()) {
+ sigAlgo = "RS256";
+ }
+
+ JwtToken jwt = jwtConsumer.getJwtToken();
+ String jwksUri = getProperty(trustedIdp, JWKS_URI);
+ JsonWebKey verifyingKey = null;
+
+ if (jwksUri != null && jwt.getJwsHeaders() != null
+ && jwt.getJwsHeaders().containsHeader(JoseConstants.HEADER_KEY_ID)) {
+ String kid = (String)jwt.getJwsHeaders().getHeader(JoseConstants.HEADER_KEY_ID);
+ LOG.debug("Attemping to retrieve key id {} from uri {}", kid, jwksUri);
+ List<Object> jsonKeyProviders = new ArrayList<Object>();
+ jsonKeyProviders.add(new JsonWebKeysProvider());
+
+ WebClient client =
+ WebClient.create(jwksUri, jsonKeyProviders, "cxf-tls.xml");
+ client.accept("application/json");
+
+ ClientConfiguration config = WebClient.getConfig(client);
+ if (LOG.isDebugEnabled()) {
+ config.getOutInterceptors().add(new LoggingOutInterceptor());
+ config.getInInterceptors().add(new LoggingInInterceptor());
+ }
+
+ Response response = client.get();
+ JsonWebKeys jsonWebKeys = response.readEntity(JsonWebKeys.class);
+ if (jsonWebKeys != null) {
+ verifyingKey = jsonWebKeys.getKey(kid);
+ }
+ }
+
+ if (verifyingKey != null) {
+ return jwtConsumer.verifySignatureWith(verifyingKey, SignatureAlgorithm.getAlgorithm(sigAlgo));
+ }
+
+ X509Certificate validatingCert = getCertificate(trustedIdp.getCertificate());
+ if (validatingCert != null) {
+ return jwtConsumer.verifySignatureWith(validatingCert, SignatureAlgorithm.getAlgorithm(sigAlgo));
+ }
+
+ LOG.warn("No key supplied to verify the signature of the IdToken");
+ return false;
+ }
+
private Crypto getCrypto(String certificate) throws ProcessingException {
if (certificate == null) {
return null;