You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by jb...@apache.org on 2016/01/20 18:17:34 UTC

[2/2] cxf-fediz git commit: Adding RealmExtensionIdentityMapper

Adding RealmExtensionIdentityMapper


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

Branch: refs/heads/master
Commit: 31a6884f3306309ac74eb85d81b3ef7d52d05650
Parents: 8009104
Author: Jan Bernhardt <jb...@talend.com>
Authored: Wed Jan 20 17:59:27 2016 +0100
Committer: Jan Bernhardt <jb...@talend.com>
Committed: Wed Jan 20 17:59:27 2016 +0100

----------------------------------------------------------------------
 .../realms/RealmExtensionIdentityMapper.java    | 74 ++++++++++++++++
 .../service/sts/realms/SamlRealmCodec.java      | 28 ++++--
 .../RealmExtensionIdentityMapperTest.java       | 90 ++++++++++++++++++++
 3 files changed, 186 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/31a6884f/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/RealmExtensionIdentityMapper.java
----------------------------------------------------------------------
diff --git a/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/RealmExtensionIdentityMapper.java b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/RealmExtensionIdentityMapper.java
new file mode 100644
index 0000000..f30caca
--- /dev/null
+++ b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/RealmExtensionIdentityMapper.java
@@ -0,0 +1,74 @@
+/**
+ * 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.sts.realms;
+
+import java.security.Principal;
+
+import org.apache.cxf.sts.IdentityMapper;
+import org.apache.wss4j.common.principal.CustomTokenPrincipal;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A test implementation of IdentityMapper.
+ */
+public class RealmExtensionIdentityMapper implements IdentityMapper {
+
+    public static final String DEFAULT_DELIMITER = "@";
+
+    private static final Logger LOG = LoggerFactory.getLogger(RealmExtensionIdentityMapper.class);
+
+    private String delimiter = DEFAULT_DELIMITER;
+
+    /**
+     * Map a principal in the source realm to the target realm
+     * 
+     * @param sourceRealm the source realm of the Principal
+     * @param sourcePrincipal the principal in the source realm
+     * @param targetRealm the target realm of the Principal
+     * @return the principal in the target realm
+     */
+    public Principal mapPrincipal(String sourceRealm, Principal sourcePrincipal, String targetRealm) {
+        if (sourcePrincipal == null) {
+            return null;
+        }
+
+        String name = sourcePrincipal.getName().toLowerCase();
+        if (name.contains(delimiter)) {
+            // Remove previous realm
+            name = name.substring(0, name.indexOf(delimiter));
+        }
+        // Add target realm
+        name = name + getDelimiter() + targetRealm;
+
+        LOG.debug("Principal '{}' mapped to '{}'", sourcePrincipal.getName(), name);
+
+        return new CustomTokenPrincipal(name);
+    }
+
+    public String getDelimiter() {
+        return delimiter;
+    }
+
+    public void setDelimiter(String delimiter) {
+        this.delimiter = delimiter;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/31a6884f/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/SamlRealmCodec.java
----------------------------------------------------------------------
diff --git a/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/SamlRealmCodec.java b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/SamlRealmCodec.java
index 2ad3b49..46d9689 100644
--- a/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/SamlRealmCodec.java
+++ b/services/sts/src/main/java/org/apache/cxf/fediz/service/sts/realms/SamlRealmCodec.java
@@ -21,8 +21,6 @@ package org.apache.cxf.fediz.service.sts.realms;
 
 import java.security.cert.X509Certificate;
 
-import javax.security.auth.x500.X500Principal;
-
 import org.apache.cxf.sts.token.realm.SAMLRealmCodec;
 import org.apache.wss4j.common.saml.SAMLKeyInfo;
 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
@@ -33,15 +31,33 @@ public class SamlRealmCodec implements SAMLRealmCodec {
 
     private static final Logger LOG = LoggerFactory.getLogger(SamlRealmCodec.class);
 
+    private boolean uppercase = true;
+    
     @Override
     public String getRealmFromToken(SamlAssertionWrapper assertion) {
         SAMLKeyInfo ki = assertion.getSignatureKeyInfo();
         X509Certificate[] certs = ki.getCerts();
-        X500Principal subject = certs[0].getSubjectX500Principal();
-        String name = subject.getName();
-        String realm = name.substring(name.indexOf("CN=") + 3);
+        String realm = parseCNValue(certs[0].getSubjectX500Principal().getName());
         LOG.info("Realm parsed in certificate: " + realm);
-        return realm.toUpperCase();
+        return realm;
+    }
+
+    protected String parseCNValue(String name) {
+        int len = name.indexOf(",") > 0 ? name.indexOf(",") : name.length();
+        String realm = name.substring(name.indexOf("CN=") + 3, len);
+        
+        if (uppercase) {
+            realm = realm.toUpperCase();
+        }
+        return realm;
+    }
+
+    public boolean isUppercase() {
+        return uppercase;
+    }
+
+    public void setUppercase(boolean uppercase) {
+        this.uppercase = uppercase;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/31a6884f/services/sts/src/test/java/org/apache/cxf/fediz/sts/realms/RealmExtensionIdentityMapperTest.java
----------------------------------------------------------------------
diff --git a/services/sts/src/test/java/org/apache/cxf/fediz/sts/realms/RealmExtensionIdentityMapperTest.java b/services/sts/src/test/java/org/apache/cxf/fediz/sts/realms/RealmExtensionIdentityMapperTest.java
new file mode 100644
index 0000000..1cbac3e
--- /dev/null
+++ b/services/sts/src/test/java/org/apache/cxf/fediz/sts/realms/RealmExtensionIdentityMapperTest.java
@@ -0,0 +1,90 @@
+/**
+ * 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.sts.realms;
+
+import java.security.Principal;
+
+import org.apache.cxf.fediz.service.sts.realms.RealmExtensionIdentityMapper;
+import org.apache.wss4j.common.principal.CustomTokenPrincipal;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * A test implementation of IdentityMapper.
+ */
+public class RealmExtensionIdentityMapperTest {
+
+    @Test
+    public void testDefaultDelimiterInitialization() {
+        RealmExtensionIdentityMapper im = new RealmExtensionIdentityMapper();
+        assertEquals(RealmExtensionIdentityMapper.DEFAULT_DELIMITER, im.getDelimiter());
+    }
+    
+    @Test
+    public void testRealmMappingSimpleUser() {
+        RealmExtensionIdentityMapper im = new RealmExtensionIdentityMapper();
+        Principal result = im.mapPrincipal("realm-a", new CustomTokenPrincipal("user"), "realm-b");
+        assertNotNull(result);
+        assertEquals("user@realm-b", result.getName());
+    }
+    
+    @Test
+    public void testRealmMappingComplexUser() {
+        RealmExtensionIdentityMapper im = new RealmExtensionIdentityMapper();
+        Principal result = im.mapPrincipal("realm-a", new CustomTokenPrincipal("user.name@realm-a"), "realm-b");
+        assertNotNull(result);
+        assertEquals("user.name@realm-b", result.getName());
+    }
+
+    @Test
+    public void testRealmMappingComplexFakeUser() {
+        RealmExtensionIdentityMapper im = new RealmExtensionIdentityMapper();
+        Principal result = im.mapPrincipal("realm-a", new CustomTokenPrincipal("user-name@realm-a@test"), "realm-b");
+        assertNotNull(result);
+        assertEquals("user-name@realm-b", result.getName());
+    }
+    
+    @Test
+    public void testRealmMappingNullUser() {
+        RealmExtensionIdentityMapper im = new RealmExtensionIdentityMapper();
+        Principal result = im.mapPrincipal("realm-a", null, "realm-b");
+        assertNull(result);
+    }
+    
+    @Test
+    public void testRealmMappingEmptyUserName() {
+        RealmExtensionIdentityMapper im = new RealmExtensionIdentityMapper();
+        Principal result = im.mapPrincipal("realm-a", new CustomTokenPrincipal("@realm-a"), "realm-b");
+        assertNotNull(result);
+        assertEquals("@realm-b", result.getName());
+    }
+    
+    @Test
+    public void testRealmMappingCustomDelimiter() {
+        RealmExtensionIdentityMapper im = new RealmExtensionIdentityMapper();
+        im.setDelimiter(".");
+        Principal result = im.mapPrincipal("realm-a", new CustomTokenPrincipal("pre.fix@realm-a"), "realm-b");
+        assertNotNull(result);
+        assertEquals("pre.realm-b", result.getName());
+    }
+}