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 2018/09/05 16:00:37 UTC
[cxf-fediz] branch master updated: FEDIZ-229 - Provide a way to map
JWT claims into SAML attributes when converting a third party JWT token
into a SAML Token
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf-fediz.git
The following commit(s) were added to refs/heads/master by this push:
new bb3ef16 FEDIZ-229 - Provide a way to map JWT claims into SAML attributes when converting a third party JWT token into a SAML Token
bb3ef16 is described below
commit bb3ef16c1dfa4995e34cc3c622a4d144dd777970
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Wed Sep 5 17:00:16 2018 +0100
FEDIZ-229 - Provide a way to map JWT claims into SAML attributes when converting a third party JWT token into a SAML Token
---
.../AbstractTrustedIdpOAuth2ProtocolHandler.java | 31 +++++++++++-
.../fediz/service/idp/protocols/ClaimsHandler.java | 32 +++++++++++++
.../service/idp/protocols/RoleClaimsHandler.java | 56 ++++++++++++++++++++++
.../TrustedIdpFacebookProtocolHandler.java | 2 +-
.../protocols/TrustedIdpOIDCProtocolHandler.java | 3 +-
.../oidc/idp/example/IdTokenProviderImpl.java | 1 +
.../src/test/resources/realma/entities-realma.xml | 1 +
7 files changed, 123 insertions(+), 3 deletions(-)
diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/AbstractTrustedIdpOAuth2ProtocolHandler.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/AbstractTrustedIdpOAuth2ProtocolHandler.java
index a59daeb..6b62c39 100644
--- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/AbstractTrustedIdpOAuth2ProtocolHandler.java
+++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/AbstractTrustedIdpOAuth2ProtocolHandler.java
@@ -25,6 +25,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.time.Instant;
+import java.util.Collections;
import java.util.Date;
import javax.security.auth.callback.Callback;
@@ -35,14 +36,17 @@ import org.apache.cxf.fediz.core.util.CertsUtils;
import org.apache.cxf.fediz.service.idp.IdpConstants;
import org.apache.cxf.fediz.service.idp.domain.Idp;
import org.apache.cxf.fediz.service.idp.domain.TrustedIdp;
+import org.apache.cxf.jaxrs.json.basic.JsonMapObject;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.saml.SAMLCallback;
import org.apache.wss4j.common.saml.SAMLUtil;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.bean.AttributeStatementBean;
import org.apache.wss4j.common.saml.bean.ConditionsBean;
import org.apache.wss4j.common.saml.bean.SubjectBean;
import org.apache.wss4j.common.saml.bean.Version;
import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.common.util.Loader;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,6 +75,12 @@ public abstract class AbstractTrustedIdpOAuth2ProtocolHandler extends AbstractTr
*/
public static final String SCOPE = "scope";
+ /**
+ * The fully qualified class name of a ClaimsHandler implementation, designed to convert claims in a JWT token
+ * into claims in the generated SAML token.
+ */
+ public static final String CLAIMS_HANDLER = "claims.handler";
+
private static final Logger LOG = LoggerFactory.getLogger(AbstractTrustedIdpOAuth2ProtocolHandler.class);
@Override
@@ -115,7 +125,8 @@ public abstract class AbstractTrustedIdpOAuth2ProtocolHandler extends AbstractTr
}
}
- protected SamlAssertionWrapper createSamlAssertion(Idp idp, TrustedIdp trustedIdp, String subjectName,
+ protected SamlAssertionWrapper createSamlAssertion(Idp idp, TrustedIdp trustedIdp, JsonMapObject claims,
+ String subjectName,
Instant notBefore,
Instant expires) throws Exception {
SamlCallbackHandler callbackHandler = new SamlCallbackHandler();
@@ -143,6 +154,14 @@ public abstract class AbstractTrustedIdpOAuth2ProtocolHandler extends AbstractTr
}
callbackHandler.setConditionsBean(conditionsBean);
+ // Claims
+ String claimsHandler = getProperty(trustedIdp, CLAIMS_HANDLER);
+ if (claimsHandler != null) {
+ ClaimsHandler claimsHandlerImpl = (ClaimsHandler)Loader.loadClass(claimsHandler).newInstance();
+ AttributeStatementBean attrStatementBean = claimsHandlerImpl.handleClaims(claims);
+ callbackHandler.setAttrBean(attrStatementBean);
+ }
+
SAMLCallback samlCallback = new SAMLCallback();
SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
@@ -159,6 +178,7 @@ public abstract class AbstractTrustedIdpOAuth2ProtocolHandler extends AbstractTr
private ConditionsBean conditionsBean;
private SubjectBean subjectBean;
private String issuer;
+ private AttributeStatementBean attrBean;
/**
* Set the SubjectBean
@@ -197,10 +217,19 @@ public abstract class AbstractTrustedIdpOAuth2ProtocolHandler extends AbstractTr
// Set the conditions
samlCallback.setConditions(conditionsBean);
+
+ // Set the attributes
+ if (attrBean != null) {
+ samlCallback.setAttributeStatementData(Collections.singletonList(attrBean));
+ }
}
}
}
+ public void setAttrBean(AttributeStatementBean attrBean) {
+ this.attrBean = attrBean;
+ }
+
}
abstract String getScope(TrustedIdp trustedIdp);
diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/ClaimsHandler.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/ClaimsHandler.java
new file mode 100644
index 0000000..cb338dc
--- /dev/null
+++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/ClaimsHandler.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.fediz.service.idp.protocols;
+
+import org.apache.cxf.jaxrs.json.basic.JsonMapObject;
+import org.apache.wss4j.common.saml.bean.AttributeStatementBean;
+
+/**
+ * An interface to convert JWT claims into a SAML AttributeStatementBean.
+ */
+public interface ClaimsHandler {
+
+ AttributeStatementBean handleClaims(JsonMapObject claims);
+
+}
diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/RoleClaimsHandler.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/RoleClaimsHandler.java
new file mode 100644
index 0000000..8551203
--- /dev/null
+++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/RoleClaimsHandler.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.fediz.service.idp.protocols;
+
+import java.net.URI;
+import java.util.Collections;
+
+import org.apache.cxf.jaxrs.json.basic.JsonMapObject;
+import org.apache.wss4j.common.saml.bean.AttributeBean;
+import org.apache.wss4j.common.saml.bean.AttributeStatementBean;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+
+/**
+ * Convert a "role" claim into a SAML AttributeStatement
+ */
+public class RoleClaimsHandler implements ClaimsHandler {
+
+ private static final URI ROLE =
+ URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role");
+ private String nameFormat = SAML2Constants.ATTRNAME_FORMAT_UNSPECIFIED;
+
+ public AttributeStatementBean handleClaims(JsonMapObject claims) {
+ if (claims != null) {
+ String role = claims.getStringProperty("role");
+ if (role != null) {
+ AttributeStatementBean attrBean = new AttributeStatementBean();
+ AttributeBean attributeBean = new AttributeBean();
+ attributeBean.setQualifiedName(ROLE.toString());
+ attributeBean.setNameFormat(nameFormat);
+ attributeBean.setAttributeValues(Collections.singletonList(role));
+ attrBean.setSamlAttributes(Collections.singletonList(attributeBean));
+ return attrBean;
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpFacebookProtocolHandler.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpFacebookProtocolHandler.java
index bafb62c..63ebf90 100644
--- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpFacebookProtocolHandler.java
+++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpFacebookProtocolHandler.java
@@ -128,7 +128,7 @@ public class TrustedIdpFacebookProtocolHandler extends AbstractTrustedIdpOAuth2P
Instant expires = Instant.now().plusSeconds(accessToken.getExpiresIn());
SecurityToken idpToken = new SecurityToken(IDGenerator.generateID(null), null, expires);
SamlAssertionWrapper assertion =
- createSamlAssertion(idp, trustedIdp, subjectName, null, expires);
+ createSamlAssertion(idp, trustedIdp, null, subjectName, null, expires);
Document doc = DOMUtils.createDocument();
Element token = assertion.toDOM(doc);
diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
index 2b0d36f..dce403e 100644
--- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
+++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
@@ -211,7 +211,8 @@ public class TrustedIdpOIDCProtocolHandler extends AbstractTrustedIdpOAuth2Proto
// Convert into a SAML Token
SamlAssertionWrapper assertion =
- createSamlAssertion(idp, trustedIdp, (String)jwt.getClaim(subjectName), notBefore, expires);
+ createSamlAssertion(idp, trustedIdp, jwt.getClaims(), (String)jwt.getClaim(subjectName),
+ notBefore, expires);
Document doc = DOMUtils.createDocument();
Element token = assertion.toDOM(doc);
diff --git a/systests/federation/oidcIdpWebapp/src/main/java/org/apache/cxf/fediz/oidc/idp/example/IdTokenProviderImpl.java b/systests/federation/oidcIdpWebapp/src/main/java/org/apache/cxf/fediz/oidc/idp/example/IdTokenProviderImpl.java
index 5785350..44c18ce 100644
--- a/systests/federation/oidcIdpWebapp/src/main/java/org/apache/cxf/fediz/oidc/idp/example/IdTokenProviderImpl.java
+++ b/systests/federation/oidcIdpWebapp/src/main/java/org/apache/cxf/fediz/oidc/idp/example/IdTokenProviderImpl.java
@@ -46,6 +46,7 @@ public class IdTokenProviderImpl implements IdTokenProvider {
token.setSubject(authenticatedUser.getLogin().toLowerCase());
token.setClaim("preferred_username", authenticatedUser.getLogin().toLowerCase());
token.setIssuer("OIDC IdP");
+ token.setClaim("role", "user");
return token;
}
diff --git a/systests/federation/wsfed/src/test/resources/realma/entities-realma.xml b/systests/federation/wsfed/src/test/resources/realma/entities-realma.xml
index 24dc488..d5eb99c 100644
--- a/systests/federation/wsfed/src/test/resources/realma/entities-realma.xml
+++ b/systests/federation/wsfed/src/test/resources/realma/entities-realma.xml
@@ -166,6 +166,7 @@
<entry key="client.id" value="consumer-id"/>
<entry key="client.secret" value="this-is-a-secret"/>
<entry key="token.endpoint" value="https://localhost:${idp.oidc.https.port}/idpoidc/services/token"/>
+ <entry key="claims.handler" value="org.apache.cxf.fediz.service.idp.protocols.RoleClaimsHandler"/>
</util:map>
</property>
</bean>