cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject [2/6] git commit: [CXF-5925] First implementation of a JEXL Claims Mapper
Date Wed, 06 Aug 2014 15:28:51 GMT
[CXF-5925] First implementation of a JEXL Claims Mapper


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

Branch: refs/heads/2.7.x-fixes
Commit: 79285f4d772a7cd242e2148a71d75a8064c98c11
Parents: a11825e
Author: Jan Bernhardt <jbernhardt@talend.com>
Authored: Mon Aug 4 12:20:14 2014 +0200
Committer: Colm O hEigeartaigh <coheigea@apache.org>
Committed: Wed Aug 6 16:24:20 2014 +0100

----------------------------------------------------------------------
 services/sts/sts-core/pom.xml                   |   6 +-
 .../apache/cxf/sts/claims/JexlClaimsMapper.java |  76 +++++++
 .../sts/claims/mapper/JexlClaimsMapperTest.java | 207 +++++++++++++++++++
 .../src/test/resources/jexlClaimMappings.script | 127 ++++++++++++
 4 files changed, 415 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/79285f4d/services/sts/sts-core/pom.xml
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/pom.xml b/services/sts/sts-core/pom.xml
index 68d6159..35a240e 100644
--- a/services/sts/sts-core/pom.xml
+++ b/services/sts/sts-core/pom.xml
@@ -107,7 +107,11 @@
             <scope>provided</scope>
             <optional>true</optional>
         </dependency>
-             
+		<dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jexl</artifactId>
+            <version>2.1.1</version>
+        </dependency>
    </dependencies>
 
    <build>

http://git-wip-us.apache.org/repos/asf/cxf/blob/79285f4d/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/JexlClaimsMapper.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/JexlClaimsMapper.java
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/JexlClaimsMapper.java
new file mode 100644
index 0000000..c1cd1e8
--- /dev/null
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/JexlClaimsMapper.java
@@ -0,0 +1,76 @@
+/**
+ * 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.sts.claims;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import org.apache.commons.jexl2.JexlContext;
+import org.apache.commons.jexl2.JexlEngine;
+import org.apache.commons.jexl2.MapContext;
+import org.apache.commons.jexl2.Script;
+import org.apache.cxf.common.logging.LogUtils;
+
+public class JexlClaimsMapper implements ClaimsMapper {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(JexlClaimsMapper.class);
+
+    JexlEngine jexl = new JexlEngine();
+    JexlContext context = new MapContext();
+    private Script script;
+
+    public JexlClaimsMapper() {
+        // jexl.setCache(512);
+        // jexl.setLenient(false);
+        jexl.setSilent(false);
+    }
+
+    public ClaimCollection mapClaims(String sourceRealm, ClaimCollection sourceClaims,
+        String targetRealm, ClaimsParameters parameters) {
+        context.set("sourceClaims", sourceClaims);
+        context.set("targetClaims", new ClaimCollection());
+        context.set("sourceRealm", sourceRealm);
+        context.set("targetRealm", targetRealm);
+        context.set("claimsParameters", parameters);
+
+        Script s = getScript();
+        if (s == null) {
+            LOG.warning("No claim mapping script defined");
+            return new ClaimCollection(); // TODO Check if null or an exception would be
more
+                                                   // appropriate
+        } else {
+            return (ClaimCollection)s.execute(context);
+        }
+    }
+
+    public Script getScript() {
+        return script;
+    }
+
+    public void setScript(Script script) {
+        this.script = script;
+    }
+
+    public void setScript(String scriptPath) throws IOException {
+        this.script = jexl.createScript(new File(scriptPath));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/79285f4d/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java
b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java
new file mode 100644
index 0000000..9df89c7
--- /dev/null
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java
@@ -0,0 +1,207 @@
+/**
+ * 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.sts.claims.mapper;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.claims.Claim;
+import org.apache.cxf.sts.claims.ClaimCollection;
+import org.apache.cxf.sts.claims.ClaimsParameters;
+import org.apache.cxf.sts.claims.JexlClaimsMapper;
+import org.junit.Test;
+
+public class JexlClaimsMapperTest extends org.junit.Assert {
+
+    JexlClaimsMapper jcm;
+
+    public JexlClaimsMapperTest() throws IOException {
+        jcm = new JexlClaimsMapper();
+        jcm.setScript("src/test/resources/jexlClaimMappings.script");
+    }
+
+    @Test
+    public void testClaimMerge() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        assertTrue(result.size() >= 2);
+        assertEquals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", result.get(1).getClaimType()
+            .toString());
+        assertEquals(1, result.get(1).getValues().size());
+        assertEquals("Jan Bernhardt", result.get(1).getValues().get(0));
+
+        for (Claim c : result) {
+            if ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname".equals(c.getClaimType()))
{
+                fail("Only merged claim should be in result set, but not the individual claims");
+            }
+        }
+    }
+
+    @Test
+    public void testRoleMappings() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        assertTrue(result.size() >= 1);
+        assertEquals(2, result.get(0).getValues().size());
+        assertTrue(result.get(0).getValues().contains("manager"));
+        assertTrue(result.get(0).getValues().contains("administrator"));
+    }
+
+    @Test
+    public void testUnusedClaims() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        for (Claim c : result) {
+            URI claimType = c.getClaimType();
+            if (claimType != null
+                && "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/unused".equals(claimType.toString()))
{
+                fail("Claims not handled within the script should not be copied to the target
token");
+            }
+        }
+    }
+
+    @Test
+    public void testUpdateIssuer() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        assertEquals("STS-B", result.get(0).getOriginalIssuer());
+        assertEquals("NewIssuer", result.get(0).getIssuer());
+        assertEquals("STS-A", result.get(1).getOriginalIssuer());
+    }
+
+    @Test
+    public void testStaticClaim() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        Claim staticClaim = findClaim(result, 
+                                               "http://schemas.microsoft.com/identity/claims/identityprovider");
+        assertNotNull(staticClaim);
+    }
+
+    @Test
+    public void testUpperCaseClaim() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        Claim claim = findClaim(result, "http://my.schema.org/identity/claims/uppercase");
+        assertNotNull(claim);
+        assertNotNull(claim.getValues());
+        assertEquals(2, claim.getValues().size());
+        assertEquals("VALUE2", claim.getValues().get(1));
+    }
+
+    @Test
+    public void testLowerCaseClaim() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        Claim claim = findClaim(result, "http://my.schema.org/identity/claims/lowercase");
+        assertNotNull(claim);
+        assertNotNull(claim.getValues());
+        assertEquals(2, claim.getValues().size());
+        assertEquals("value2", claim.getValues().get(1));
+    }
+
+    @Test
+    public void testWrappedUpperCaseClaim() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        Claim claim = findClaim(result, "http://my.schema.org/identity/claims/wrappedUppercase");
+        assertNotNull(claim);
+        assertNotNull(claim.getValues());
+        assertEquals(1, claim.getValues().size());
+        assertEquals("PREFIX_VALUE_SUFFIX", claim.getValues().get(0));
+    }
+
+    @Test
+    public void testSimpleClaimCopy() throws IOException {
+        ClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties());
+
+        assertNotNull(result);
+        Claim claim = findClaim(result, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mail");
+        assertNotNull(claim);
+        assertNotNull(claim.getValues());
+        assertEquals(1, claim.getValues().size());
+        assertEquals("test@apache.com", claim.getValues().get(0));
+    }
+
+    @SuppressWarnings("unchecked")
+    protected ClaimCollection createClaimCollection() {
+        ClaimCollection cc = new ClaimCollection();
+        Claim c = new Claim();
+        c.setIssuer("STS-A");
+        c.setOriginalIssuer("STS-B");
+        c.setClaimType(URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"));
+        c.setValues(Arrays.asList("admin", "manager", "tester"));
+        cc.add(c);
+
+        c = new Claim();
+        c.setIssuer("STS-A");
+        c.setClaimType(URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"));
+        c.setValues(Arrays.asList("Jan"));
+        cc.add(c);
+
+        c = new Claim();
+        c.setIssuer("STS-A");
+        c.setClaimType(URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"));
+        c.setValues(Arrays.asList("Bernhardt"));
+        cc.add(c);
+
+        c = new Claim();
+        c.setClaimType(URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/unused"));
+        c.setValues(Arrays.asList("noValue"));
+        cc.add(c);
+
+        c = new Claim();
+        c.setClaimType(URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mail"));
+        c.setValues(Arrays.asList("test@apache.com"));
+        cc.add(c);
+
+        return cc;
+    }
+
+    protected ClaimsParameters createProperties() {
+        StaticSTSProperties stsProp = new StaticSTSProperties();
+        stsProp.setIssuer("NewIssuer");
+        ClaimsParameters param = new ClaimsParameters();
+        param.setStsProperties(stsProp);
+        return param;
+    }
+
+    private Claim findClaim(ClaimCollection claims, String claimType) {
+        if (claimType == null || claims == null) {
+            return null;
+        }
+        for (Claim c : claims) {
+            if (c.getClaimType() != null && claimType.equals(c.getClaimType().toString()))
{
+                return c;
+            }
+        }
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/79285f4d/services/sts/sts-core/src/test/resources/jexlClaimMappings.script
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/resources/jexlClaimMappings.script b/services/sts/sts-core/src/test/resources/jexlClaimMappings.script
new file mode 100644
index 0000000..b477088
--- /dev/null
+++ b/services/sts/sts-core/src/test/resources/jexlClaimMappings.script
@@ -0,0 +1,127 @@
+/**
+ * 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.
+ */
+
+{
+    // Role value mapping
+    var roleClaimType = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role';
+    var roleMappings = { "admin" : "administrator", "manager" : "manager" };
+    
+    for (c : sourceClaims) {
+    	if(c.claimType == roleClaimType) {
+	    	var mappedValues = new("java.util.ArrayList");
+	    	for (v : c.values) {
+	    		var newValue = roleMappings.get(v);
+	    		if (newValue != null) {
+	    			mappedValues.add(newValue);
+	    		}
+	    	}
+	    	c.values = mappedValues;
+	    	targetClaims.add(c);
+    	}
+    }
+    
+    // Claim merge
+    var firstNameClaimType = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname';
+    var lastNameClaimType = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname';
+    var firstName;
+    var lastName;
+    var issuer;
+    for (c : sourceClaims) {
+    	if(c.claimType == firstNameClaimType) {
+    		firstName = c.values[0];
+    		issuer = c.issuer;
+    	} else if(c.claimType == lastNameClaimType) {
+    		lastName = c.values[0];
+    	}
+    }
+    if (firstName != null && lastName != null) {
+    	var claim = new("org.apache.cxf.sts.claims.Claim");
+    	claim.issuer = issuer;
+    	claim.claimType = new("java.net.URI", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name");
+    	claim.addValue(firstName + " " + lastName);
+    	targetClaims.add(claim);
+    }
+    
+    // Additional static claim
+    var idpClaim = new("org.apache.cxf.sts.claims.Claim");
+    idpClaim.claimType = new("java.net.URI", "http://schemas.microsoft.com/identity/claims/identityprovider");
+    idpClaim.value = "https://idp.apache.org/cbb375d-33b-45fa-9bf5-f33bd8721a77/";
+    targetClaims.add(idpClaim);
+    
+    // Claim value updates
+    var uppercaseClaim = new("org.apache.cxf.sts.claims.Claim");
+    uppercaseClaim.claimType = new("java.net.URI", "http://my.schema.org/identity/claims/uppercase");
+    uppercaseClaim.values.add("Value");
+    uppercaseClaim.values.add("Value2");
+    var newValues = new("java.util.ArrayList");
+    for (v : uppercaseClaim.values) {
+    	newValue = v.toUpperCase();
+    	newValues.add(newValue);
+    }
+    uppercaseClaim.values = newValues;
+    targetClaims.add(uppercaseClaim);
+    
+    var lowercaseClaim = new("org.apache.cxf.sts.claims.Claim");
+    lowercaseClaim.claimType = new("java.net.URI", "http://my.schema.org/identity/claims/lowercase");
+    lowercaseClaim.values.add("Value");
+    lowercaseClaim.values.add("Value2");
+    var newValues = new("java.util.ArrayList");
+    for (v : lowercaseClaim.values) {
+    	newValue = v.toLowerCase();
+    	newValues.add(newValue);
+    }
+    lowercaseClaim.values = newValues;
+    targetClaims.add(lowercaseClaim);
+    
+    var wrappedUppercaseClaim = new("org.apache.cxf.sts.claims.Claim");
+    wrappedUppercaseClaim.claimType = new("java.net.URI", "http://my.schema.org/identity/claims/wrappedUppercase");
+    wrappedUppercaseClaim.values.add("Value");
+    var newValues = new("java.util.ArrayList");
+    for (v : wrappedUppercaseClaim.values) {
+    	newValue = "Prefix_" + v + "_Suffix";
+    	newValues.add(newValue);
+    }
+    wrappedUppercaseClaim.values = newValues;
+    var newValues = new("java.util.ArrayList");
+    for (v : wrappedUppercaseClaim.values) {
+    	newValue = v.toUpperCase();
+    	newValues.add(newValue);
+    }
+    wrappedUppercaseClaim.values = newValues;
+    targetClaims.add(wrappedUppercaseClaim);
+    
+    // Direct copy
+    var emailClaimType = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mail';
+    for (c : sourceClaims) {
+    	if(c.claimType == emailClaimType) {
+    		targetClaims.add(c);
+    	}
+    }
+    
+    // Set correct issuer
+    for (c : targetClaims) {
+    	if(c.originalIssuer == null) {
+    		c.originalIssuer = c.issuer;
+    	}
+    	c.issuer = claimsParameters.stsProperties.issuer;
+    }
+    
+    // Return new claims
+    return targetClaims;
+}


Mime
View raw message