Commit 89715ed3 authored by michael.simon's avatar michael.simon
Browse files

add possibility to use every saml attribute as primary identifier

parent b0a0e2eb
...@@ -20,7 +20,13 @@ public class SamlUserEntity extends UserEntity { ...@@ -20,7 +20,13 @@ public class SamlUserEntity extends UserEntity {
@Column(name = "persistent_spid", length = 1024) @Column(name = "persistent_spid", length = 1024)
private String persistentSpId; private String persistentSpId;
@Column(name = "attr_src_id", length = 1024)
private String attributeSourcedId;
@Column(name = "attr_src_id_name", length = 1024)
private String attributeSourcedIdName;
@ManyToOne(targetEntity = SamlIdpMetadataEntity.class) @ManyToOne(targetEntity = SamlIdpMetadataEntity.class)
private SamlIdpMetadataEntity idp; private SamlIdpMetadataEntity idp;
...@@ -66,4 +72,20 @@ public class SamlUserEntity extends UserEntity { ...@@ -66,4 +72,20 @@ public class SamlUserEntity extends UserEntity {
public void setSubjectId(String subjectId) { public void setSubjectId(String subjectId) {
this.subjectId = subjectId; this.subjectId = subjectId;
} }
public String getAttributeSourcedId() {
return attributeSourcedId;
}
public void setAttributeSourcedId(String attributeSourcedId) {
this.attributeSourcedId = attributeSourcedId;
}
public String getAttributeSourcedIdName() {
return attributeSourcedIdName;
}
public void setAttributeSourcedIdName(String attributeSourcedIdName) {
this.attributeSourcedIdName = attributeSourcedIdName;
}
} }
...@@ -22,4 +22,5 @@ public interface SamlUserDao extends BaseDao<SamlUserEntity, Long> { ...@@ -22,4 +22,5 @@ public interface SamlUserDao extends BaseDao<SamlUserEntity, Long> {
SamlUserEntity findByEppn(String eppn); SamlUserEntity findByEppn(String eppn);
SamlUserEntity findByIdWithStore(Long id); SamlUserEntity findByIdWithStore(Long id);
SamlUserEntity findByPersistent(String spId, String idpId, String persistentId); SamlUserEntity findByPersistent(String spId, String idpId, String persistentId);
SamlUserEntity findByAttributeSourcedId(String spId, String idpId, String attributeSourcedIdName, String attributeSourcedId);
} }
...@@ -92,6 +92,22 @@ public class JpaSamlUserDao extends JpaBaseDao<SamlUserEntity, Long> implements ...@@ -92,6 +92,22 @@ public class JpaSamlUserDao extends JpaBaseDao<SamlUserEntity, Long> implements
} }
} }
@Override
public SamlUserEntity findByAttributeSourcedId(String spId, String idpId, String attributeSourcedIdName, String attributeSourcedId) {
TypedQuery<SamlUserEntity> query = em.createQuery("select u from SamlUserEntity u where u.persistentSpId = :spId and u.idp.entityId = :idpId and "
+ "u.attributeSourcedIdName = :attributeSourcedIdName and u.attributeSourcedId = :attributeSourcedId", SamlUserEntity.class)
.setParameter("spId", spId).setParameter("idpId", idpId)
.setParameter("attributeSourcedIdName", attributeSourcedIdName).setParameter("attributeSourcedId", attributeSourcedId);
try {
return query.getSingleResult();
}
catch (NoResultException e) {
return null;
}
}
@Override @Override
public SamlUserEntity findByEppn(String eppn) { public SamlUserEntity findByEppn(String eppn) {
CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaBuilder builder = em.getCriteriaBuilder();
......
...@@ -50,6 +50,7 @@ import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver; ...@@ -50,6 +50,7 @@ import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
import org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver; import org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver;
import org.slf4j.Logger; import org.slf4j.Logger;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity; import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.SamlIdpScopeEntity; import edu.kit.scc.webreg.entity.SamlIdpScopeEntity;
import edu.kit.scc.webreg.entity.SamlMetadataEntity; import edu.kit.scc.webreg.entity.SamlMetadataEntity;
...@@ -78,6 +79,9 @@ public class Saml2AssertionService { ...@@ -78,6 +79,9 @@ public class Saml2AssertionService {
@Inject @Inject
private ScriptingEnv scriptingEnv; private ScriptingEnv scriptingEnv;
@Inject
private ApplicationConfig appConfig;
public Assertion processSamlResponse(Response samlResponse, SamlMetadataEntity idpEntity, public Assertion processSamlResponse(Response samlResponse, SamlMetadataEntity idpEntity,
EntityDescriptor idpEntityDescriptor, SamlSpConfigurationEntity spEntity) EntityDescriptor idpEntityDescriptor, SamlSpConfigurationEntity spEntity)
throws IOException, DecryptionException, SamlAuthenticationException { throws IOException, DecryptionException, SamlAuthenticationException {
...@@ -171,6 +175,28 @@ public class Saml2AssertionService { ...@@ -171,6 +175,28 @@ public class Saml2AssertionService {
} }
} }
String identifier = null;
if (appConfig.getConfigValue("saml_id_attribute") != null) {
identifier = appConfig.getConfigValue("saml_id_attribute");
}
if (idpEntity.getGenericStore().containsKey("saml_id_attribute")) {
identifier = idpEntity.getGenericStore().get("saml_id_attribute");
}
if (identifier != null) {
String idValue = samlIdentifier.getAttributeMap().get(identifier);
samlIdentifier.setAttributeSourcedIdName(identifier);
samlIdentifier.setAttributeSourcedId(idValue);
if (idValue != null) {
return scriptingEnv.getSamlUserDao().findByAttributeSourcedId(samlSpEntityId, idpEntity.getEntityId(), identifier, idValue);
}
else {
throw new SamlAuthenticationException("Identifier not found. Global configured identifier is: " + identifier);
}
}
/* /*
* prefer pairwise-id over persistent over subject-id * prefer pairwise-id over persistent over subject-id
*/ */
...@@ -220,6 +246,12 @@ public class Saml2AssertionService { ...@@ -220,6 +246,12 @@ public class Saml2AssertionService {
if (samlIdentifier.getSubjectId() != null) { if (samlIdentifier.getSubjectId() != null) {
user.setSubjectId(samlIdentifier.getSubjectId()); user.setSubjectId(samlIdentifier.getSubjectId());
} }
if (samlIdentifier.getAttributeSourcedId() != null && samlIdentifier.getAttributeSourcedIdName() != null) {
user.setAttributeSourcedId(samlIdentifier.getAttributeSourcedId());
user.setAttributeSourcedIdName(samlIdentifier.getAttributeSourcedIdName());
}
} }
} }
...@@ -230,6 +262,7 @@ public class Saml2AssertionService { ...@@ -230,6 +262,7 @@ public class Saml2AssertionService {
String pairwiseId = null; String pairwiseId = null;
String subjectId = null; String subjectId = null;
String transientId = null; String transientId = null;
Map<String, String> attributeMap = new HashMap<String, String>();
logger.debug("Looking up pairwise ID\n"); logger.debug("Looking up pairwise ID\n");
...@@ -244,6 +277,12 @@ public class Saml2AssertionService { ...@@ -244,6 +277,12 @@ public class Saml2AssertionService {
else if (attribute.getName().equals("urn:oasis:names:tc:SAML:attribute:subject-id")) { else if (attribute.getName().equals("urn:oasis:names:tc:SAML:attribute:subject-id")) {
subjectId = getIdFromAttribute(idpEntity, attribute, debugLog); subjectId = getIdFromAttribute(idpEntity, attribute, debugLog);
} }
else {
if (attribute.getAttributeValues().size() == 1) {
Object o = attribute.getAttributeValues().get(0);
attributeMap.put(attribute.getName(), o.toString());
}
}
if (debugLog != null) if (debugLog != null)
debugLog.append("\n"); debugLog.append("\n");
...@@ -317,7 +356,7 @@ public class Saml2AssertionService { ...@@ -317,7 +356,7 @@ public class Saml2AssertionService {
throw new SamlAuthenticationException("Unsupported SAML2 NameID Type"); throw new SamlAuthenticationException("Unsupported SAML2 NameID Type");
} }
return new SamlIdentifier(persistentId, pairwiseId, subjectId, transientId); return new SamlIdentifier(persistentId, pairwiseId, subjectId, transientId, attributeMap);
} }
protected String getIdFromAttribute(SamlIdpMetadataEntity idpEntity, Attribute attribute, StringBuffer debugLog) { protected String getIdFromAttribute(SamlIdpMetadataEntity idpEntity, Attribute attribute, StringBuffer debugLog) {
......
package edu.kit.scc.webreg.service.saml; package edu.kit.scc.webreg.service.saml;
import java.io.Serializable; import java.io.Serializable;
import java.util.Map;
public class SamlIdentifier implements Serializable { public class SamlIdentifier implements Serializable {
...@@ -10,13 +11,17 @@ public class SamlIdentifier implements Serializable { ...@@ -10,13 +11,17 @@ public class SamlIdentifier implements Serializable {
private String pairwiseId; private String pairwiseId;
private String subjectId; private String subjectId;
private String transientId; private String transientId;
private Map<String, String> attributeMap;
private String attributeSourcedId;
private String attributeSourcedIdName;
public SamlIdentifier(String persistentId, String pairwiseId, String subjectId, String transientId) { public SamlIdentifier(String persistentId, String pairwiseId, String subjectId, String transientId, Map<String, String> attributeMap) {
super(); super();
this.persistentId = persistentId; this.persistentId = persistentId;
this.pairwiseId = pairwiseId; this.pairwiseId = pairwiseId;
this.subjectId = subjectId; this.subjectId = subjectId;
this.transientId = transientId; this.transientId = transientId;
this.attributeMap = attributeMap;
} }
public String getPersistentId() { public String getPersistentId() {
...@@ -34,5 +39,25 @@ public class SamlIdentifier implements Serializable { ...@@ -34,5 +39,25 @@ public class SamlIdentifier implements Serializable {
public String getTransientId() { public String getTransientId() {
return transientId; return transientId;
} }
public Map<String, String> getAttributeMap() {
return attributeMap;
}
public String getAttributeSourcedId() {
return attributeSourcedId;
}
public void setAttributeSourcedId(String attributeSourcedId) {
this.attributeSourcedId = attributeSourcedId;
}
public String getAttributeSourcedIdName() {
return attributeSourcedIdName;
}
public void setAttributeSourcedIdName(String attributeSourcedIdName) {
this.attributeSourcedIdName = attributeSourcedIdName;
}
} }
Markdown is supported
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