Commit 08a1e813 authored by michael.simon's avatar michael.simon
Browse files

Add filter capability for idps when called from saml service

parent 52d2ef91
......@@ -12,6 +12,7 @@ package edu.kit.scc.webreg.dao;
import java.util.List;
import edu.kit.scc.webreg.entity.SamlIdpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlSpMetadataEntity;
import edu.kit.scc.webreg.entity.ServiceEntity;
import edu.kit.scc.webreg.entity.ServiceSamlSpEntity;
......@@ -21,5 +22,7 @@ public interface ServiceSamlSpDao extends BaseDao<ServiceSamlSpEntity, Long> {
List<ServiceSamlSpEntity> findByService(ServiceEntity service);
List<ServiceSamlSpEntity> findBySamlSp(SamlSpMetadataEntity sp);
List<ServiceSamlSpEntity> findBySamlSpAndIdp(SamlIdpConfigurationEntity idp, SamlSpMetadataEntity sp);
}
......@@ -19,6 +19,7 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import edu.kit.scc.webreg.dao.ServiceSamlSpDao;
import edu.kit.scc.webreg.entity.SamlIdpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlSpMetadataEntity;
import edu.kit.scc.webreg.entity.ServiceEntity;
import edu.kit.scc.webreg.entity.ServiceSamlSpEntity;
......@@ -38,6 +39,20 @@ public class JpaServiceSamlSpDao extends JpaBaseDao<ServiceSamlSpEntity, Long> i
return em.createQuery(criteria).getResultList();
}
@Override
public List<ServiceSamlSpEntity> findBySamlSpAndIdp(SamlIdpConfigurationEntity idp, SamlSpMetadataEntity sp) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<ServiceSamlSpEntity> criteria = builder.createQuery(ServiceSamlSpEntity.class);
Root<ServiceSamlSpEntity> root = criteria.from(ServiceSamlSpEntity.class);
criteria.where(
builder.and(
builder.equal(root.get("sp"), sp),
builder.equal(root.get("idp"), idp)
));
criteria.select(root);
return em.createQuery(criteria).getResultList();
}
@Override
public List<ServiceSamlSpEntity> findBySamlSp(SamlSpMetadataEntity sp) {
CriteriaBuilder builder = em.getCriteriaBuilder();
......
......@@ -10,7 +10,11 @@
******************************************************************************/
package edu.kit.scc.webreg.service;
import java.util.List;
import edu.kit.scc.webreg.entity.SamlIdpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlSpMetadataEntity;
import edu.kit.scc.webreg.entity.ServiceSamlSpEntity;
public interface SamlIdpConfigurationService extends BaseService<SamlIdpConfigurationEntity, Long> {
......@@ -18,4 +22,6 @@ public interface SamlIdpConfigurationService extends BaseService<SamlIdpConfigur
SamlIdpConfigurationEntity findByEntityId(String entityId);
List<ServiceSamlSpEntity> findBySamlSpAndIdp(SamlIdpConfigurationEntity idpConfig, SamlSpMetadataEntity spMetadata);
}
......@@ -10,12 +10,17 @@
******************************************************************************/
package edu.kit.scc.webreg.service.impl;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
import edu.kit.scc.webreg.dao.BaseDao;
import edu.kit.scc.webreg.dao.SamlIdpConfigurationDao;
import edu.kit.scc.webreg.dao.ServiceSamlSpDao;
import edu.kit.scc.webreg.entity.SamlIdpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlSpMetadataEntity;
import edu.kit.scc.webreg.entity.ServiceSamlSpEntity;
import edu.kit.scc.webreg.service.SamlIdpConfigurationService;
@Stateless
......@@ -26,6 +31,9 @@ public class SamlIdpConfigurationServiceImpl extends BaseServiceImpl<SamlIdpConf
@Inject
private SamlIdpConfigurationDao dao;
@Inject
private ServiceSamlSpDao serviceSamlSpDao;
@Override
public SamlIdpConfigurationEntity findByEntityId(String entityId) {
return dao.findByEntityId(entityId);
......@@ -36,6 +44,12 @@ public class SamlIdpConfigurationServiceImpl extends BaseServiceImpl<SamlIdpConf
return dao.findByHostname(hostname);
}
@Override
public List<ServiceSamlSpEntity> findBySamlSpAndIdp(SamlIdpConfigurationEntity idpConfig,
SamlSpMetadataEntity spMetadata) {
return serviceSamlSpDao.findBySamlSpAndIdp(idpConfig, spMetadata);
}
@Override
protected BaseDao<SamlIdpConfigurationEntity, Long> getDao() {
return dao;
......
......@@ -10,6 +10,10 @@ import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.inject.Inject;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.slf4j.Logger;
......@@ -17,6 +21,7 @@ import edu.kit.scc.webreg.dao.FederationDao;
import edu.kit.scc.webreg.dao.SamlIdpMetadataDao;
import edu.kit.scc.webreg.entity.FederationEntity;
import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.ScriptEntity;
@Singleton
public class FederationSingletonBean {
......@@ -41,25 +46,29 @@ public class FederationSingletonBean {
logger.info("Constructing federation cache");
federationCache = new HashMap<FederationEntity, List<SamlIdpMetadataEntity>>();
idpMap = new HashMap<String, SamlIdpMetadataEntity>();
lastRefresh = 0L;
refreshCache();
}
public void refreshCache() {
sortedFederationList = federationDao.findAll();
if (System.currentTimeMillis() - lastRefresh > 1000L * 60L * 60L) {
idpMap.clear();
for (FederationEntity federation : sortedFederationList) {
logger.info("Loading federation {} ({})", federation.getId(), federation.getEntityId());
sortedFederationList = federationDao.findAll();
idpMap.clear();
List<SamlIdpMetadataEntity> idpList = idpDao.findAllByFederationOrderByOrgname(federation);
federationCache.put(federation, idpList);
for (SamlIdpMetadataEntity idp : idpList) {
idpMap.put(idp.getEntityId(), idp);
for (FederationEntity federation : sortedFederationList) {
logger.info("Loading federation {} ({})", federation.getId(), federation.getEntityId());
List<SamlIdpMetadataEntity> idpList = idpDao.findAllByFederationOrderByOrgname(federation);
federationCache.put(federation, idpList);
for (SamlIdpMetadataEntity idp : idpList) {
idpMap.put(idp.getEntityId(), idp);
}
}
lastRefresh = System.currentTimeMillis();
}
lastRefresh = System.currentTimeMillis();
}
public List<FederationEntity> getFederationList() {
......@@ -69,11 +78,37 @@ public class FederationSingletonBean {
public List<SamlIdpMetadataEntity> getIdpList(FederationEntity federationEntity) {
return federationCache.get(federationEntity);
}
public List<SamlIdpMetadataEntity> getFilteredIdpList(ScriptEntity scriptEntity) {
refreshCache();
ScriptEngine engine = (new ScriptEngineManager()).getEngineByName(scriptEntity.getScriptEngine());
List<SamlIdpMetadataEntity> tempList = new ArrayList<SamlIdpMetadataEntity>(idpMap.values());
if (engine == null) {
logger.warn("No engine set for script {}. Returning all IDPs", scriptEntity.getName());
return tempList;
}
try {
engine.eval(scriptEntity.getScript());
Invocable invocable = (Invocable) engine;
invocable.invokeFunction("filterIdps", tempList, logger);
} catch (ScriptException e) {
logger.warn("Script execution failed.", e);
} catch (NoSuchMethodException e) {
logger.info("No filterIdps method in script. returning all Idps");
}
return tempList;
}
public List<SamlIdpMetadataEntity> getAllIdpList() {
if (System.currentTimeMillis() - lastRefresh > 1000L * 60L * 60L) {
refreshCache();
}
refreshCache();
List<SamlIdpMetadataEntity> tempList = new ArrayList<SamlIdpMetadataEntity>(idpMap.values());
Collections.sort(tempList, new Comparator<SamlIdpMetadataEntity>() {
......
......@@ -34,6 +34,7 @@ public class SessionManager implements Serializable {
private Long authnRequestId;
private Long authnRequestIdpConfigId;
private Long authnRequestSpMetadataId;
// identityId of the actual user
private Long identityId;
......@@ -305,4 +306,12 @@ public class SessionManager implements Serializable {
public void setSubjectId(String subjectId) {
this.subjectId = subjectId;
}
public Long getAuthnRequestSpMetadataId() {
return authnRequestSpMetadataId;
}
public void setAuthnRequestSpMetadataId(Long authnRequestSpMetadataId) {
this.authnRequestSpMetadataId = authnRequestSpMetadataId;
}
}
......@@ -22,16 +22,27 @@ import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.entity.FederationEntity;
import edu.kit.scc.webreg.entity.SamlIdpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.SamlSpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlSpMetadataEntity;
import edu.kit.scc.webreg.entity.ScriptEntity;
import edu.kit.scc.webreg.entity.ServiceSamlSpEntity;
import edu.kit.scc.webreg.entity.oidc.OidcRpConfigurationEntity;
import edu.kit.scc.webreg.service.SamlIdpConfigurationService;
import edu.kit.scc.webreg.service.SamlIdpMetadataService;
import edu.kit.scc.webreg.service.SamlSpConfigurationService;
import edu.kit.scc.webreg.service.SamlSpMetadataService;
import edu.kit.scc.webreg.service.oidc.OidcRpConfigurationService;
import edu.kit.scc.webreg.service.saml.FederationSingletonBean;
import edu.kit.scc.webreg.service.saml.exc.SamlAuthenticationException;
import edu.kit.scc.webreg.session.SessionManager;
import edu.kit.scc.webreg.util.FacesMessageGenerator;
......@@ -62,6 +73,12 @@ public class DiscoveryLoginBean implements Serializable {
@Inject
private ApplicationConfig appConfig;
@Inject
private SamlIdpConfigurationService idpConfigService;
@Inject
private SamlSpMetadataService spMetadataService;
private List<FederationEntity> federationList;
private List<SamlIdpMetadataEntity> idpList;
private FederationEntity selectedFederation;
......@@ -72,6 +89,9 @@ public class DiscoveryLoginBean implements Serializable {
private String filter;
private SamlSpMetadataEntity spMetadata;
private SamlIdpConfigurationEntity idpConfig;
private Boolean initialized = false;
public void preRenderView(ComponentSystemEvent ev) {
......@@ -90,7 +110,6 @@ public class DiscoveryLoginBean implements Serializable {
messageGenerator.addErrorMessage("Das SAML Subsystem ist noch nicht konfiguriert");
return;
}
//selectedFederation = federationList.get(0);
updateIdpList();
initialized = true;
}
......@@ -144,7 +163,25 @@ public class DiscoveryLoginBean implements Serializable {
public void updateIdpList() {
if (selectedFederation == null) {
idpList = federationBean.getAllIdpList();
if (sessionManager.getAuthnRequestIdpConfigId() == null && sessionManager.getAuthnRequestSpMetadataId() == null) {
/*
* reg-app login directly called
*/
idpList = federationBean.getAllIdpList();
}
else {
/*
* reg-app login called via service provider/ relying party
*/
idpConfig = idpConfigService.findById(sessionManager.getAuthnRequestIdpConfigId());
spMetadata = spMetadataService.findById(sessionManager.getAuthnRequestSpMetadataId());
List<ServiceSamlSpEntity> serviceSamlList = idpConfigService.findBySamlSpAndIdp(idpConfig, spMetadata);
for (ServiceSamlSpEntity serviceSaml : serviceSamlList) {
if (serviceSaml.getScript() != null) {
idpList.addAll(federationBean.getFilteredIdpList(serviceSaml.getScript()));
}
}
}
}
else {
idpList = federationBean.getIdpList(selectedFederation);
......@@ -227,4 +264,12 @@ public class DiscoveryLoginBean implements Serializable {
return appConfig;
}
public SamlSpMetadataEntity getSpMetadata() {
return spMetadata;
}
public SamlIdpConfigurationEntity getIdpConfig() {
return idpConfig;
}
}
......@@ -85,6 +85,11 @@ public class Saml2IdpRedirectHandler {
throw new ServletException("SAML Authentication Request ist not complete, issuer data is missing");
}
if (! idpConfig.getEntityId().equals(authnRequest.getDestination())) {
logger.warn("EntityId from AuthnRequest ({}) does not match SamlIdpConfig EntityId ({}). This is probably some misconfig somewhere.",
authnRequest.getDestination(), idpConfig.getEntityId());
}
SamlSpMetadataEntity spMetadata = spService.findByEntityId(authnRequest.getIssuer().getValue());
if (spMetadata == null) {
......@@ -99,6 +104,7 @@ public class Saml2IdpRedirectHandler {
long id = samlIdpService.registerAuthnRequest(authnRequest);
session.setAuthnRequestId(id);
session.setAuthnRequestIdpConfigId(idpConfig.getId());
session.setAuthnRequestSpMetadataId(spMetadata.getId());
session.setOriginalRequestPath(idpConfig.getRedirect() + "/response");
response.sendRedirect("/welcome/index.xhtml");
return;
......@@ -107,6 +113,7 @@ public class Saml2IdpRedirectHandler {
long id = samlIdpService.registerAuthnRequest(authnRequest);
session.setAuthnRequestId(id);
session.setAuthnRequestIdpConfigId(idpConfig.getId());
session.setAuthnRequestSpMetadataId(spMetadata.getId());
response.sendRedirect(request.getRequestURI() + "/response");
}
}
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