Commit 10ec4787 authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

726: Finalize v1.0 for release with Schema Registry

Task-Url: https://minfba.de.dariah.eu/mantisbt/view.php?id=726
parent dbf321a0
......@@ -17,17 +17,20 @@ public class SAMLRequiredAttributesList {
public SAMLRequiredAttributes[] getRequiredAttributes() { return requiredAttributes; }
public SAMLRequiredAttributesList(ObjectMapper objectMapper, String strRequiredAttributes) throws Exception {
public SAMLRequiredAttributesList(ObjectMapper objectMapper, String strRequiredAttributes) {
SAMLRequiredAttributes[] requiredAttributes = null;
try {
requiredAttributes = objectMapper.readValue(strRequiredAttributes, SAMLRequiredAttributes[].class);
if (strRequiredAttributes!=null) {
requiredAttributes = objectMapper.readValue(strRequiredAttributes, SAMLRequiredAttributes[].class);
}
} catch (Exception e) {
logger.error("Failed to deserialize required attributes from configuration", e);
throw e;
}
this.requiredAttributes = requiredAttributes;
}
public List<SAMLRequiredAttributes> getForStage(AUTHENTICATION_STAGE stage, boolean requiredOnly) {
if (stage==null || this.size()==0) {
if (requiredAttributes==null || stage==null || this.size()==0) {
return null;
}
List<SAMLRequiredAttributes> result = new ArrayList<SAMLRequiredAttributes>();
......
......@@ -24,7 +24,10 @@ import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.security.credential.Credential;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.saml.key.KeyManager;
import org.springframework.security.saml.metadata.*;
import org.springframework.security.saml.util.SAMLUtil;
......@@ -51,7 +54,7 @@ import static org.springframework.util.StringUtils.hasLength;
*/
@Controller
@RequestMapping("/saml/web/metadata")
public class MetadataController {
public class MetadataController implements ApplicationContextAware {
private final Logger log = LoggerFactory.getLogger(MetadataController.class);
......@@ -59,10 +62,16 @@ public class MetadataController {
SSO_POST, SSO_PAOS, SSO_ARTIFACT, HOKSSO_POST, HOKSSO_ARTIFACT
}
@Autowired MetadataManager metadataManager;
@Autowired KeyManager keyManager;
@RequestMapping
@Autowired private MetadataManager metadataManager;
@Autowired private KeyManager keyManager;
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@RequestMapping
public String metadataList(Model model) throws MetadataProviderException {
model.addAttribute("hostedSP", metadataManager.getHostedSPName());
model.addAttribute("spList", metadataManager.getSPEntityNames());
......@@ -129,15 +138,17 @@ public class MetadataController {
}
ExtendedMetadata extendedMetadata = new ExtendedMetadata();
MetadataGenerator generator = new MetadataGenerator();
generator.setKeyManager(keyManager);
generator.setExtendedMetadata(extendedMetadata);
MetadataGenerator metadataGenerator = applicationContext.getBean(MetadataGenerator.class);
metadataGenerator.setKeyManager(keyManager);
metadataGenerator.setExtendedMetadata(extendedMetadata);
// Basic metadata properties
generator.setEntityId(metadata.getEntityId());
generator.setEntityBaseURL(metadata.getBaseURL());
generator.setRequestSigned(metadata.isRequestSigned());
generator.setWantAssertionSigned(metadata.isWantAssertionSigned());
metadataGenerator.setEntityId(metadata.getEntityId());
metadataGenerator.setEntityBaseURL(metadata.getBaseURL());
metadataGenerator.setRequestSigned(metadata.isRequestSigned());
metadataGenerator.setWantAssertionSigned(metadata.isWantAssertionSigned());
Collection<String> bindingsSSO = new LinkedList<String>();
Collection<String> bindingsHoKSSO = new LinkedList<String>();
......@@ -163,12 +174,12 @@ public class MetadataController {
}
// Set bindings
generator.setBindingsSSO(bindingsSSO);
generator.setBindingsHoKSSO(bindingsHoKSSO);
generator.setAssertionConsumerIndex(assertionConsumerIndex);
metadataGenerator.setBindingsSSO(bindingsSSO);
metadataGenerator.setBindingsHoKSSO(bindingsHoKSSO);
metadataGenerator.setAssertionConsumerIndex(assertionConsumerIndex);
// Name IDs
generator.setNameID(Arrays.asList(metadata.getNameID()));
metadataGenerator.setNameID(Arrays.asList(metadata.getNameID()));
// Keys
extendedMetadata.setSigningKey(metadata.getSigningKey());
......@@ -180,7 +191,7 @@ public class MetadataController {
// Discovery
if (metadata.isIncludeDiscovery()) {
extendedMetadata.setIdpDiscoveryEnabled(true);
generator.setIncludeDiscoveryExtension(metadata.isIncludeDiscoveryExtension());
metadataGenerator.setIncludeDiscoveryExtension(metadata.isIncludeDiscoveryExtension());
if (metadata.getCustomDiscoveryURL() != null && metadata.getCustomDiscoveryURL().length() > 0) {
extendedMetadata.setIdpDiscoveryURL(metadata.getCustomDiscoveryURL());
}
......@@ -189,7 +200,7 @@ public class MetadataController {
}
} else {
extendedMetadata.setIdpDiscoveryEnabled(false);
generator.setIncludeDiscoveryExtension(false);
metadataGenerator.setIncludeDiscoveryExtension(false);
}
// Alias
......@@ -213,8 +224,8 @@ public class MetadataController {
}
// Generate values
EntityDescriptor generatedDescriptor = generator.generateMetadata();
ExtendedMetadata generatedExtendedMetadata = generator.generateExtendedMetadata();
EntityDescriptor generatedDescriptor = metadataGenerator.generateMetadata();
ExtendedMetadata generatedExtendedMetadata = metadataGenerator.generateExtendedMetadata();
if (metadata.isStore()) {
......@@ -422,5 +433,4 @@ public class MetadataController {
public String getTabName() {
return "metadata";
}
}
\ No newline at end of file
auth:
local:
users:
- username: 'admin'
passhash: '$2a$10$nbXRnAx5wKurTrbaUkT/MOLXKAJgpT8R71/jujzPwgXXrG.OqlBKW'
roles: ["ROLE_ADMINISTRATOR"]
- username: 'tgradl'
passhash: '$2a$10$EeajSQQUepa7H7.g4xQCaeO.hjUwh0yzYCMrfOkWCZGe1IiWaexa6'
roles: ["ROLE_CONTRIBUTOR"]
saml:
keystore:
path: /data/_srv/minfba/minfba-de-dariah-eu.jks
# Comment if keystore is not protected by password
pass: 'hairad'
alias: minfba.de.dariah.eu
aliaspass: 'hairad'
sp:
requiredAttributes:
- stage: ATTRIBUTES
required: true
attributeGroup:
- check: AND
attributes:
- friendlyName: mail
name: urn:oid:0.9.2342.19200300.100.1.3
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
- stage: ATTRIBUTES
required: true
attributeGroup:
- check: OR
attributes:
- friendlyName: dariahTermsOfUse
name: urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value: Terms_of_Use_v5.pdf
- friendlyName: dariahTermsOfUse
name: urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value: foobar-service-agreement_version1.pdf
- stage: AUTHENTICATION
required: true
attributeGroup:
- check: AND
attributes:
- friendlyName: eduPersonPrincipalName
name: urn:oid:1.3.6.1.4.1.5923.1.1.1.6
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
- stage: AUTHENTICATION
required: false
attributeGroup:
- check: OPTIONAL
attributes:
- friendlyName: mail
name: urn:oid:0.9.2342.19200300.100.1.3
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
- friendlyName: displayName
name: urn:oid:2.16.840.1.113730.3.1.241
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
\ No newline at end of file
auth:
local:
users:
- username: 'admin'
passhash: '$2a$10$nbXRnAx5wKurTrbaUkT/MOLXKAJgpT8R71/jujzPwgXXrG.OqlBKW'
roles: ["ROLE_ADMINISTRATOR"]
- username: 'tgradl'
passhash: '$2a$10$EeajSQQUepa7H7.g4xQCaeO.hjUwh0yzYCMrfOkWCZGe1IiWaexa6'
roles: ["ROLE_CONTRIBUTOR"]
saml:
keystore:
path: /data/_srv/schereg/key/dfa-de-dariah-eu.jks
# Uncomment if keystore is protected by password
#pass: 'somepass'
alias: dfa.de.dariah.eu
aliaspass: ''
metadata:
url: https://www.aai.dfn.de/fileadmin/metadata/dfn-aai-test-metadata.xml
#url: https://www.aai.dfn.de/fileadmin/metadata/dfn-aai-basic-metadata.xml
sp:
externalMetadata: /home/tobias/Downloads/spring_saml_metadata.xml
alias: dariahsp
baseUrr: https://minfba.de.dariah.eu/dariahsp
entityId: minfba.de.dariah.eu_dariahsp
securityProfile: metaiop
sslSecurityProfile: pkix
sslHostnameVerification: default
signMetadata: true
signingAlgorithm: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
signingKey: minfba.de.dariah.eu
encryptionKey: minfba.de.dariah.eu
tlsKey: minfba.de.dariah.eu
requireArtifactResolveSigned: true
requireAttributeQuerySigned: false
requireLogoutRequestSigned: true
requireLogoutResponseSigned: false
discovery:
enabled: true
url: https://minfba.de.dariah.eu/dariahsp/saml/login/alias/dariahsp?disco:true
return: https://minfba.de.dariah.eu/dariahsp/saml/discovery/alias/dariahsp
allowedNameIds : EMAIL, TRANSIENT, PERSISTENT, UNSPECIFIED, X509_SUBJECT
# Attribute querying
attributeQuery:
enabled: true
excludedEndpoints:
urls: ["https://ldap-dariah-clone.esc.rzg.mpg.de/idp/shibboleth", "https://idp.de.dariah.eu/idp/shibboleth"]
assumeAttributesComplete: true
queryIdp: https://ldap-dariah-clone.esc.rzg.mpg.de/idp/shibboleth
#queryIdp: https://idp.de.dariah.eu/idp/shibboleth
queryByNameID: false
queryAttribute:
friendlyName: eduPersonPrincipalName
name: urn:oid:1.3.6.1.4.1.5923.1.1.1.6
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
# For now without parameters bc DARIAH Self Service is broken
incompleteAttributesRedirect: "https://dariah.daasi.de/Shibboleth.sso/Login?target=/cgi-bin/selfservice/ldapportal.pl"
#incompleteAttributesRedirect: "https://dariah.daasi.de/Shibboleth.sso/Login?target=/cgi-bin/selfservice/ldapportal.pl%3Fmode%3Dauthenticate%3Bshibboleth%3D1%3Bnextpage%3Dregistration%3Breturnurl%3D{returnUrl}&entityID={entityId}"
#incompleteAttributesRedirect: "https://auth.dariah.eu/Shibboleth.sso/Login?target=/cgi-bin/selfservice/ldapportal.pl%3Fmode%3Dauthenticate%3Bshibboleth%3D1%3Bnextpage%3Dregistration%3Breturnurl%3D{returnUrl}&entityID={entityId}"
requiredAttributes:
- stage: ATTRIBUTES
required: true
attributeGroup:
- check: AND
attributes:
- friendlyName: mail
name: urn:oid:0.9.2342.19200300.100.1.3
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
- stage: ATTRIBUTES
required: true
attributeGroup:
- check: OR
attributes:
- friendlyName: dariahTermsOfUse
name: urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value: Terms_of_Use_v5.pdf
- friendlyName: dariahTermsOfUse
name: urn:oid:1.3.6.1.4.1.10126.1.52.4.15
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
value: foobar-service-agreement_version1.pdf
- stage: AUTHENTICATION
required: true
attributeGroup:
- check: AND
attributes:
- friendlyName: eduPersonPrincipalName
name: urn:oid:1.3.6.1.4.1.5923.1.1.1.6
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
- stage: AUTHENTICATION
required: false
attributeGroup:
- check: OPTIONAL
attributes:
- friendlyName: mail
name: urn:oid:0.9.2342.19200300.100.1.3
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
- friendlyName: displayName
name: urn:oid:2.16.840.1.113730.3.1.241
nameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri
\ No newline at end of file
......@@ -8,7 +8,7 @@
<context:annotation-config/>
<bean id="configLocation" class="java.lang.String">
<constructor-arg value="classpath:dariahsp_local_sample.yml" />
<constructor-arg value="classpath:dariahsp.yml" />
</bean>
<bean id="properties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
<property name="resources" ref="configLocation"/>
......
......@@ -66,6 +66,17 @@
<property name="defaultAuthority" value="Authenticated User" />
</bean>
<!-- Filter automatically generates default SP metadata -->
<!-- Utilized only if no path to external metadata has been set (compare bean id="metadata") -->
<bean id="metadataGeneratorFilter" class="eu.dariah.de.dariahsp.saml.metadata.ConditionalMetadataGeneratorFilter">
<constructor-arg ref="metadataGenerator" />
<constructor-arg value="#{'${auth.saml.sp.externalMetadata:null}'!='null'}" />
</bean>
<bean id="requiredAttributes" class="eu.dariah.de.dariahsp.saml.attributequery.options.SAMLRequiredAttributesList">
<constructor-arg ref="objectMapper" />
<constructor-arg value="${auth.saml.sp.requiredAttributes:#{null}}" />
</bean>
<bean id="redirectionAwareFilter" class="eu.dariah.de.dariahsp.web.RedirectionAwareFilterBean" />
<bean id="redirectCache" class="eu.dariah.de.dariahsp.web.RedirectCache" />
......
......@@ -33,8 +33,11 @@
<security:request-cache ref="requestCache"/>
</security:http> -->
<bean id="metadataGeneratorFilter" class="eu.dariah.de.dariahsp.local.MetadataGeneratorDummyFilterBean" />
<bean id="metadataGenerator" class="eu.dariah.de.dariahsp.saml.metadata.AttributeMetadataGenerator" scope="prototype">
<property name="requiredAttributes" ref="requiredAttributes" />
</bean>
<!-- Filters for processing of local authentication -->
<bean id="authFilter" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map request-matcher="ant">
......
......@@ -57,27 +57,15 @@
<bean id="samlIDPDiscovery" class="org.springframework.security.saml.SAMLDiscovery">
<property name="idpSelectionPath" value="/WEB-INF/security/idpSelection.jsp"/>
</bean>
<bean id="externalLocalSpMetadataConfigured" class="java.lang.Boolean">
<constructor-arg value="#{'${auth.saml.sp.externalMetadata:null}'!='null'}" />
<bean id="metadataGenerator" class="eu.dariah.de.dariahsp.saml.metadata.AttributeMetadataGenerator" scope="prototype">
<property name="entityBaseURL" value="${auth.saml.sp.baseUrl}" />
<property name="entityId" value="${auth.saml.sp.entityId}" />
<property name="includeDiscoveryExtension" value="${auth.saml.sp.discovery.enabled}" />
<property name="nameID" value="#{'${auth.saml.sp.allowedNameIds:EMAIL,TRANSIENT,PERSISTENT,UNSPECIFIED,X509_SUBJECT}'.split(',')}" />
<property name="extendedMetadata" ref="localSpMetadata" />
<property name="requiredAttributes" ref="requiredAttributes" />
</bean>
<!-- Filter automatically generates default SP metadata -->
<!-- Utilized only if no path to external metadata has been set (compare bean id="metadata") -->
<bean id="metadataGeneratorFilter" class="eu.dariah.de.dariahsp.saml.metadata.ConditionalMetadataGeneratorFilter">
<constructor-arg>
<bean class="eu.dariah.de.dariahsp.saml.metadata.AttributeMetadataGenerator">
<property name="entityBaseURL" value="${auth.saml.sp.baseUrl}" />
<property name="entityId" value="${auth.saml.sp.entityId}" />
<property name="includeDiscoveryExtension" value="${auth.saml.sp.discovery.enabled}" />
<property name="nameID" value="#{'${auth.saml.sp.allowedNameIds:EMAIL,TRANSIENT,PERSISTENT,UNSPECIFIED,X509_SUBJECT}'.split(',')}" />
<property name="extendedMetadata" ref="localSpMetadata" />
<property name="requiredAttributes" ref="requiredAttributes" />
</bean>
</constructor-arg>
<constructor-arg ref="externalLocalSpMetadataConfigured" />
</bean>
<!-- Utilized only if path to external metadata has been set (compare bean id="metadata") -->
<bean id="externalMetadata" class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
......@@ -215,12 +203,7 @@
</property>
<property name="requiredAttributesList" ref="requiredAttributes" />
</bean>
<bean id="requiredAttributes" class="eu.dariah.de.dariahsp.saml.attributequery.options.SAMLRequiredAttributesList">
<constructor-arg ref="objectMapper" />
<constructor-arg value="${auth.saml.sp.requiredAttributes:#{null}}" />
</bean>
<bean id="attributeQuery" class="eu.dariah.de.dariahsp.saml.attributequery.SAMLAttributeQueryImpl">
<constructor-arg>
<bean class="org.apache.commons.httpclient.HttpClient" />
......
......@@ -96,33 +96,33 @@
<label class="col-sm-3 control-label">Configuration:</label>
<div class="col-sm-9">
<textarea id="configuration" readonly="readonly" class="form-control" rows="12"># Append these properties to your application configuration
saml.sp.
auth:
...
saml:
...
sp:
# Modify this property to point to the downloaded SP metadata
externalMetadata = /path/to/downloaded/spring-saml-metadata.xml
alias = ${metadata.alias}
baseUrl = ${baseUrl}
entityId = ${metadata.entityId}
securityProfile = ${metadata.securityProfile}
sslSecurityProfile = ${metadata.sslSecurityProfile}
sslHostnameVerification = ${metadata.sslHostnameVerification}
signMetadata = ${metadata.signMetadata}
signingAlgorithm = ${metadata.signingAlgorithm}
signingKey = ${metadata.signingKey}
encryptionKey = ${metadata.encryptionKey}
tlsKey = ${metadata.tlsKey}
requireArtifactResolveSigned = ${metadata.requireArtifactResolveSigned}
requireAttributeQuerySigned = ${metadata.requireAttributeQuerySigned}
requireLogoutRequestSigned = ${metadata.requireLogoutRequestSigned}
requireLogoutResponseSigned = ${metadata.requireLogoutResponseSigned}
discovery.enabled = ${metadata.includeDiscovery}
discovery.url = ${metadata.customDiscoveryURL}
discovery.return = ${metadata.customDiscoveryResponseURL}
allowedNameIds = <c:forEach begin="0" end="${fn:length(metadata.nameID) - 1}" var="index"><c:out value="${metadata.nameID[index]}"/><c:if test="${index < fn:length(metadata.nameID)-1}">, </c:if></c:forEach>
externalMetadata: /path/to/downloaded/spring-saml-metadata.xml
alias: ${metadata.alias}
baseUrl: ${baseUrl}
entityId: ${metadata.entityId}
securityProfile: ${metadata.securityProfile}
sslSecurityProfile: ${metadata.sslSecurityProfile}
sslHostnameVerification: ${metadata.sslHostnameVerification}
signMetadata: ${metadata.signMetadata}
signingAlgorithm: ${metadata.signingAlgorithm}
signingKey: ${metadata.signingKey}
encryptionKey: ${metadata.encryptionKey}
tlsKey: ${metadata.tlsKey}
requireArtifactResolveSigned: ${metadata.requireArtifactResolveSigned}
requireAttributeQuerySigned: ${metadata.requireAttributeQuerySigned}
requireLogoutRequestSigned: ${metadata.requireLogoutRequestSigned}
requireLogoutResponseSigned: ${metadata.requireLogoutResponseSigned}
discovery:
enabled: ${metadata.includeDiscovery}
url: ${metadata.customDiscoveryURL}
return: ${metadata.customDiscoveryResponseURL}
allowedNameIds: <c:forEach begin="0" end="${fn:length(metadata.nameID) - 1}" var="index"><c:out value="${metadata.nameID[index]}"/><c:if test="${index < fn:length(metadata.nameID)-1}">, </c:if></c:forEach>
</textarea>
</div>
</div>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment