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 2015/03/23 18:26:18 UTC

cxf-fediz git commit: More work on configuring SAML SSO in Fediz

Repository: cxf-fediz
Updated Branches:
  refs/heads/master f7cf8d8cd -> f499c0408


More work on configuring SAML SSO in Fediz


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

Branch: refs/heads/master
Commit: f499c040815db3a831fe8a5d7ef39d601096c320
Parents: f7cf8d8
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Mon Mar 23 17:25:58 2015 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Mon Mar 23 17:25:58 2015 +0000

----------------------------------------------------------------------
 .../fediz/service/idp/domain/TrustedIdp.java    |  16 ++-
 .../service/idp/model/TrustedIDPConfig.java     | 131 +------------------
 .../TrustedIdpSAMLProtocolHandler.java          |  66 ++++++++--
 .../idp/service/jpa/TrustedIdpDAOJPAImpl.java   |   4 +-
 .../idp/service/jpa/TrustedIdpEntity.java       |  24 +++-
 .../src/test/resources/entities-realma.xml      |   6 +-
 6 files changed, 93 insertions(+), 154 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f499c040/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/domain/TrustedIdp.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/domain/TrustedIdp.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/domain/TrustedIdp.java
index 6469372..803d75f 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/domain/TrustedIdp.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/domain/TrustedIdp.java
@@ -19,6 +19,8 @@
 package org.apache.cxf.fediz.service.idp.domain;
 
 import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -26,7 +28,7 @@ import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "trustedIdp", namespace = "http://org.apache.cxf.fediz/")
 @XmlType(propOrder = {"realm", "url", "name", "description", "protocol", "trustType",
-                      "certificate", "federationType", "cacheTokens", "logo", "id", "signRequest" })
+                      "certificate", "federationType", "cacheTokens", "logo", "id", "parameters" })
 //@XmlAttribute on Id must be set on getter, not on attribute, otherwise error
 public class TrustedIdp implements Serializable {
 
@@ -69,8 +71,8 @@ public class TrustedIdp implements Serializable {
     //optional (to provide a list of IDPs)
     protected String logo;
     
-    // Whether to sign a request to the trusted IdP or not
-    private boolean signRequest;
+    // Additional (possibly protocol specific parameters)
+    protected Map<String, String> parameters = new HashMap<String, String>();
 
     
     @XmlAttribute
@@ -162,12 +164,12 @@ public class TrustedIdp implements Serializable {
         this.trustType = trustType;
     }
 
-    public boolean isSignRequest() {
-        return signRequest;
+    public Map<String, String> getParameters() {
+        return parameters;
     }
 
-    public void setSignRequest(boolean signRequest) {
-        this.signRequest = signRequest;
+    public void setParameters(Map<String, String> parameters) {
+        this.parameters = parameters;
     }
                
 

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f499c040/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/model/TrustedIDPConfig.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/model/TrustedIDPConfig.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/model/TrustedIDPConfig.java
index e511fb5..89c2bbb 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/model/TrustedIDPConfig.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/model/TrustedIDPConfig.java
@@ -19,141 +19,12 @@
 package org.apache.cxf.fediz.service.idp.model;
 
 
-import javax.xml.bind.annotation.XmlAttribute;
-
-import org.apache.cxf.fediz.service.idp.domain.FederationType;
-import org.apache.cxf.fediz.service.idp.domain.TrustType;
 import org.apache.cxf.fediz.service.idp.domain.TrustedIdp;
 
 //@XmlRootElement(name = "TrustedIDP", namespace = "http://org.apache.cxf.fediz")
 public class TrustedIDPConfig extends TrustedIdp {
 
-    private static final long serialVersionUID = 7017232258951933643L;
-
-    private int id;
-
-    //@Column(name = "REALM", nullable = true, length = FIELD_LENGTH)
-    private String realm;  //wtrealm, whr
-
-    // Should tokens be cached from trusted IDPs
-    // to avoid redirection to the trusted IDP again for next SignIn request
-    private boolean cacheTokens;
-    
-    //Could be read from Metadata, PassiveRequestorEndpoint
-    private String url;
-    
-    //Could be read from Metadata, md:KeyDescriptor, use="signing"
-    //Store certificate in DB or filesystem, provide options?
-    private String certificate;
-    
-    //Direct trust (signing cert imported), Indirect trust (CA certs imported, subject configured)
-    private TrustType trustType;
-    
-    //Could be read from Metadata, RoleDescriptor protocolSupportEnumeration=
-    // "http://docs.oasis-open.org/wsfed/federation/200706"
-    // Metadata could provide more than one but one must be chosen
-    private String protocol;
-    
-    //FederateIdentity, FederateClaims
-    private FederationType federationType;
-    
-    //optional (to provide a list of IDPs)
-    private String name;
-    
-    //optional (to provide a list of IDPs)
-    private String description;
-    
-    //optional (to provide a list of IDPs)
-    private String logo;
-
-    @XmlAttribute
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-    
-    public String getRealm() {
-        return realm;
-    }
-
-    public void setRealm(String realm) {
-        this.realm = realm;
-    }
-
-    public boolean isCacheTokens() {
-        return cacheTokens;
-    }
-
-    public void setCacheTokens(boolean cacheTokens) {
-        this.cacheTokens = cacheTokens;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    public String getCertificate() {
-        return certificate;
-    }
-
-    public void setCertificate(String certificate) {
-        this.certificate = certificate;
-    }
-
-    public String getProtocol() {
-        return protocol;
-    }
-
-    public void setProtocol(String protocol) {
-        this.protocol = protocol;
-    }
-
-    public FederationType getFederationType() {
-        return federationType;
-    }
-
-    public void setFederationType(FederationType federationType) {
-        this.federationType = federationType;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getLogo() {
-        return logo;
-    }
-
-    public void setLogo(String logo) {
-        this.logo = logo;
-    }
-
-    public TrustType getTrustType() {
-        return trustType;
-    }
+    private static final long serialVersionUID = -1182000443945024801L;
 
-    public void setTrustType(TrustType trustType) {
-        this.trustType = trustType;
-    }
-               
 
 }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f499c040/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
index 9cb089d..1b52eaf 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
@@ -31,6 +31,7 @@ import java.security.Signature;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.Map;
 import java.util.zip.DataFormatException;
 
 import javax.servlet.http.HttpServletRequest;
@@ -78,6 +79,10 @@ import org.springframework.webflow.execution.RequestContext;
 
 @Component
 public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler {
+    public static final String SIGN_REQUEST = "sign.request";
+    public static final String REQUIRE_KEYINFO = "require.keyinfo";
+    public static final String REQUIRE_SIGNED_ASSERTIONS = "require.signed.assertions";
+    public static final String REQUIRE_KNOWN_ISSUER = "require.known.issuer";
 
     public static final String PROTOCOL = "urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser";
 
@@ -85,7 +90,6 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
     private static final String SAML_SSO_REQUEST_ID = "saml-sso-request-id";
 
     private AuthnRequestBuilder authnRequestBuilder = new DefaultAuthnRequestBuilder();
-    // private long stateTimeToLive = SSOConstants.DEFAULT_STATE_TIME;
 
     static {
         OpenSAMLUtil.initSamlEngine();
@@ -113,7 +117,9 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
                 authnRequestBuilder.createAuthnRequest(
                     null, idp.getRealm(), idp.getIdpUrl().toString()
                 );
-            if (trustedIdp.isSignRequest()) {
+            
+            boolean signRequest = isSignRequest(trustedIdp);
+            if (signRequest) {
                 authnRequest.setDestination(trustedIdp.getUrl());
             }
             Element authnRequestElement = OpenSAMLUtil.toDom(authnRequest, doc);
@@ -129,7 +135,7 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
             if (wctx != null) {
                 ub.queryParam(SSOConstants.RELAY_STATE, wctx);
             }
-            if (trustedIdp.isSignRequest()) {
+            if (signRequest) {
                 signRequest(urlEncodedRequest, wctx, idp, ub);
             }
             
@@ -166,7 +172,7 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
             org.opensaml.saml2.core.Response samlResponse = readSAMLResponse(encodedSAMLResponse);
             
             Crypto crypto = getCrypto(trustedIdp.getCertificate());
-            validateSamlResponseProtocol(samlResponse, crypto);
+            validateSamlResponseProtocol(samlResponse, crypto, trustedIdp);
             // Validate the Response
             SSOValidatorResponse validatorResponse = 
                 validateSamlSSOResponse(samlResponse, idp, trustedIdp, context);
@@ -342,11 +348,11 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
      * Validate the received SAML Response as per the protocol
      */
     private void validateSamlResponseProtocol(
-        org.opensaml.saml2.core.Response samlResponse, Crypto crypto
+        org.opensaml.saml2.core.Response samlResponse, Crypto crypto, TrustedIdp trustedIdp
     ) {
         try {
             SAMLProtocolResponseValidator protocolValidator = new SAMLProtocolResponseValidator();
-            protocolValidator.setKeyInfoMustBeAvailable(true);
+            protocolValidator.setKeyInfoMustBeAvailable(isRequireKeyInfo(trustedIdp));
             protocolValidator.validateSamlResponse(samlResponse, crypto, null);
         } catch (WSSecurityException ex) {
             LOG.debug(ex.getMessage(), ex);
@@ -378,8 +384,8 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
                 (String)WebUtils.getAttributeFromExternalContext(requestContext, SAML_SSO_REQUEST_ID);
             ssoResponseValidator.setRequestId(requestId);
             ssoResponseValidator.setSpIdentifier(idp.getRealm());
-            ssoResponseValidator.setEnforceAssertionsSigned(true);
-            ssoResponseValidator.setEnforceKnownIssuer(true);
+            ssoResponseValidator.setEnforceAssertionsSigned(isRequireSignedAssertions(trustedIdp));
+            ssoResponseValidator.setEnforceKnownIssuer(isRequireKnownIssuer(trustedIdp));
 
             return ssoResponseValidator.validateSamlResponse(samlResponse, false);
         } catch (WSSecurityException ex) {
@@ -388,5 +394,49 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
         }
     }
 
+    private boolean isSignRequest(TrustedIdp trustedIdp) {
+        Map<String, String> parameters = trustedIdp.getParameters();
+        
+        if (parameters != null && parameters.containsKey(SIGN_REQUEST)) {
+            return Boolean.parseBoolean(parameters.get(SIGN_REQUEST));
+        }
+        
+        // Sign the request by default
+        return true;
+    }
+    
+    private boolean isRequireKeyInfo(TrustedIdp trustedIdp) {
+        Map<String, String> parameters = trustedIdp.getParameters();
+        
+        if (parameters != null && parameters.containsKey(REQUIRE_KEYINFO)) {
+            return Boolean.parseBoolean(parameters.get(REQUIRE_KEYINFO));
+        }
+        
+        // Require KeyInfo by default
+        return true;
+    }
+    
+    private boolean isRequireSignedAssertions(TrustedIdp trustedIdp) {
+        Map<String, String> parameters = trustedIdp.getParameters();
+        
+        if (parameters != null && parameters.containsKey(REQUIRE_SIGNED_ASSERTIONS)) {
+            return Boolean.parseBoolean(parameters.get(REQUIRE_SIGNED_ASSERTIONS));
+        }
+        
+        // Require signed Assertions by default
+        return true;
+    }
+    
+    private boolean isRequireKnownIssuer(TrustedIdp trustedIdp) {
+        Map<String, String> parameters = trustedIdp.getParameters();
+        
+        if (parameters != null && parameters.containsKey(REQUIRE_KNOWN_ISSUER)) {
+            return Boolean.parseBoolean(parameters.get(REQUIRE_KNOWN_ISSUER));
+        }
+        
+        // Require known issuers by default by default
+        return true;
+    }
+    
 
 }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f499c040/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpDAOJPAImpl.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpDAOJPAImpl.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpDAOJPAImpl.java
index a7b5472..b95af01 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpDAOJPAImpl.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpDAOJPAImpl.java
@@ -129,7 +129,7 @@ public class TrustedIdpDAOJPAImpl implements TrustedIdpDAO {
         entity.setRealm(trustedIDP.getRealm());
         entity.setTrustType(trustedIDP.getTrustType());
         entity.setUrl(trustedIDP.getUrl());
-        entity.setSignRequest(trustedIDP.isSignRequest());
+        entity.setParameters(trustedIDP.getParameters());
     }
     
     public static TrustedIdp entity2domain(TrustedIdpEntity entity) {
@@ -145,7 +145,7 @@ public class TrustedIdpDAOJPAImpl implements TrustedIdpDAO {
         trustedIDP.setRealm(entity.getRealm());
         trustedIDP.setTrustType(entity.getTrustType());
         trustedIDP.setUrl(entity.getUrl());
-        trustedIDP.setSignRequest(entity.isSignRequest());
+        trustedIDP.setParameters(entity.getParameters());
         return trustedIDP;
     }
 

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f499c040/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpEntity.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpEntity.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpEntity.java
index 11785c7..22ac57a 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpEntity.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/service/jpa/TrustedIdpEntity.java
@@ -18,10 +18,18 @@
  */
 package org.apache.cxf.fediz.service.idp.service.jpa;
 
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.MapKeyColumn;
 import javax.validation.constraints.NotNull;
 
 import org.apache.cxf.fediz.service.idp.domain.FederationType;
@@ -76,8 +84,12 @@ public class TrustedIdpEntity {
     //optional (to provide a list of IDPs)
     private String logo;
     
-    // Whether to sign a request to the trusted IdP or not
-    private boolean signRequest;
+    // Additional (possibly protocol specific parameters)
+    @ElementCollection
+    @MapKeyColumn(name = "name")
+    @Column(name = "value")
+    @CollectionTable(name = "trusted_idp_parameters", joinColumns = @JoinColumn(name = "trusted_idp_id"))
+    private Map<String, String> parameters = new HashMap<String, String>();
     
 
     public int getId() {
@@ -168,12 +180,12 @@ public class TrustedIdpEntity {
         this.trustType = trustType;
     }
 
-    public boolean isSignRequest() {
-        return signRequest;
+    public Map<String, String> getParameters() {
+        return parameters;
     }
 
-    public void setSignRequest(boolean signRequest) {
-        this.signRequest = signRequest;
+    public void setParameters(Map<String, String> parameters) {
+        this.parameters = parameters;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f499c040/systests/federation/samlsso/src/test/resources/entities-realma.xml
----------------------------------------------------------------------
diff --git a/systests/federation/samlsso/src/test/resources/entities-realma.xml b/systests/federation/samlsso/src/test/resources/entities-realma.xml
index 649b88c..2b2b5d1 100644
--- a/systests/federation/samlsso/src/test/resources/entities-realma.xml
+++ b/systests/federation/samlsso/src/test/resources/entities-realma.xml
@@ -88,7 +88,11 @@
         <property name="federationType" value="FEDERATE_IDENTITY" />
         <property name="name" value="Realm B" />
         <property name="description" value="Realm B description" />
-        <property name="signRequest" value="true" />
+        <property name="parameters">
+            <util:map>
+                <entry key="sign.request" value="true" />
+            </util:map>
+        </property>
     </bean>
 
     <bean id="srv-fedizhelloworld" class="org.apache.cxf.fediz.service.idp.service.jpa.ApplicationEntity">