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

add possibility to use every saml attribute as primary identifier

parent b0a0e2eb
......@@ -21,6 +21,12 @@ public class SamlUserEntity extends UserEntity {
@Column(name = "persistent_spid", length = 1024)
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)
private SamlIdpMetadataEntity idp;
......@@ -66,4 +72,20 @@ public class SamlUserEntity extends UserEntity {
public void setSubjectId(String 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> {
SamlUserEntity findByEppn(String eppn);
SamlUserEntity findByIdWithStore(Long id);
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
}
}
@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
public SamlUserEntity findByEppn(String eppn) {
CriteriaBuilder builder = em.getCriteriaBuilder();
......
......@@ -50,6 +50,7 @@ import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
import org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver;
import org.slf4j.Logger;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.SamlIdpScopeEntity;
import edu.kit.scc.webreg.entity.SamlMetadataEntity;
......@@ -78,6 +79,9 @@ public class Saml2AssertionService {
@Inject
private ScriptingEnv scriptingEnv;
@Inject
private ApplicationConfig appConfig;
public Assertion processSamlResponse(Response samlResponse, SamlMetadataEntity idpEntity,
EntityDescriptor idpEntityDescriptor, SamlSpConfigurationEntity spEntity)
throws IOException, DecryptionException, SamlAuthenticationException {
......@@ -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
*/
......@@ -220,6 +246,12 @@ public class Saml2AssertionService {
if (samlIdentifier.getSubjectId() != null) {
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 {
String pairwiseId = null;
String subjectId = null;
String transientId = null;
Map<String, String> attributeMap = new HashMap<String, String>();
logger.debug("Looking up pairwise ID\n");
......@@ -244,6 +277,12 @@ public class Saml2AssertionService {
else if (attribute.getName().equals("urn:oasis:names:tc:SAML:attribute:subject-id")) {
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)
debugLog.append("\n");
......@@ -317,7 +356,7 @@ public class Saml2AssertionService {
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) {
......
package edu.kit.scc.webreg.service.saml;
import java.io.Serializable;
import java.util.Map;
public class SamlIdentifier implements Serializable {
......@@ -10,13 +11,17 @@ public class SamlIdentifier implements Serializable {
private String pairwiseId;
private String subjectId;
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();
this.persistentId = persistentId;
this.pairwiseId = pairwiseId;
this.subjectId = subjectId;
this.transientId = transientId;
this.attributeMap = attributeMap;
}
public String getPersistentId() {
......@@ -35,4 +40,24 @@ public class SamlIdentifier implements Serializable {
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