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 <[email protected]> Authored: Mon Mar 23 17:25:58 2015 +0000 Committer: Colm O hEigeartaigh <[email protected]> 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">
