Commit fc2c8ec1 authored by michael.simon's avatar michael.simon
Browse files

more changes to the saml identification process

parent 90e83c9a
......@@ -8,9 +8,11 @@ import javax.inject.Named;
import edu.kit.scc.webreg.dao.GroupDao;
import edu.kit.scc.webreg.dao.RegistryDao;
import edu.kit.scc.webreg.dao.SamlUserDao;
import edu.kit.scc.webreg.dao.ScriptDao;
import edu.kit.scc.webreg.dao.ServiceDao;
import edu.kit.scc.webreg.dao.UserDao;
import edu.kit.scc.webreg.dao.oidc.OidcUserDao;
import edu.kit.scc.webreg.dao.project.ProjectDao;
import edu.kit.scc.webreg.service.project.ProjectCreater;
import edu.kit.scc.webreg.service.project.ProjectUpdater;
......@@ -27,6 +29,12 @@ public class ScriptingEnv implements Serializable {
@Inject
private UserDao userDao;
@Inject
private SamlUserDao samlUserDao;
@Inject
private OidcUserDao oidcUserDao;
@Inject
private GroupDao groupDao;
......@@ -53,72 +61,43 @@ public class ScriptingEnv implements Serializable {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public GroupDao getGroupDao() {
return groupDao;
}
public void setGroupDao(GroupDao groupDao) {
this.groupDao = groupDao;
}
public ServiceDao getServiceDao() {
return serviceDao;
}
public void setServiceDao(ServiceDao serviceDao) {
this.serviceDao = serviceDao;
}
public RegistryDao getRegistryDao() {
return registryDao;
}
public void setRegistryDao(RegistryDao registryDao) {
this.registryDao = registryDao;
}
public ScriptDao getScriptDao() {
return scriptDao;
}
public void setScriptDao(ScriptDao scriptDao) {
this.scriptDao = scriptDao;
}
public SsoHelper getSsoHelper() {
return ssoHelper;
}
public void setSsoHelper(SsoHelper ssoHelper) {
this.ssoHelper = ssoHelper;
}
public ProjectDao getProjectDao() {
return projectDao;
}
public void setProjectDao(ProjectDao projectDao) {
this.projectDao = projectDao;
}
public ProjectCreater getProjectCreater() {
return projectCreater;
}
public void setProjectCreater(ProjectCreater projectCreater) {
this.projectCreater = projectCreater;
}
public ProjectUpdater getProjectUpdater() {
return projectUpdater;
}
public void setProjectUpdater(ProjectUpdater projectUpdater) {
this.projectUpdater = projectUpdater;
public SamlUserDao getSamlUserDao() {
return samlUserDao;
}
public OidcUserDao getOidcUserDao() {
return oidcUserDao;
}
}
......@@ -17,13 +17,14 @@ import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.SamlSpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlUserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.saml.SamlIdentifier;
public interface UserCreateService {
SamlUserEntity createUser(SamlUserEntity user, Map<String, List<Object>> attributeMap, String executor)
throws UserUpdateException;
SamlUserEntity preCreateUser(SamlIdpMetadataEntity idpEntity, SamlSpConfigurationEntity spEntity, String persistentId,
SamlUserEntity preCreateUser(SamlIdpMetadataEntity idpEntity, SamlSpConfigurationEntity spEntity, SamlIdentifier samlIdentifier,
String locale, Map<String, List<Object>> attributeMap) throws UserUpdateException;
}
......@@ -44,8 +44,11 @@ import edu.kit.scc.webreg.event.EventSubmitter;
import edu.kit.scc.webreg.event.UserEvent;
import edu.kit.scc.webreg.exc.EventSubmitException;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.SamlIdpMetadataService;
import edu.kit.scc.webreg.service.UserCreateService;
import edu.kit.scc.webreg.service.group.HomeOrgGroupUpdater;
import edu.kit.scc.webreg.service.saml.Saml2AssertionService;
import edu.kit.scc.webreg.service.saml.SamlIdentifier;
@Stateless
public class UserCreateServiceImpl implements UserCreateService {
......@@ -86,17 +89,25 @@ public class UserCreateServiceImpl implements UserCreateService {
@Inject
private ApplicationConfig appConfig;
@Inject
private Saml2AssertionService saml2AssertionService;
@Inject
private SamlIdpMetadataService idpMetadataService;
@Override
public SamlUserEntity preCreateUser(SamlIdpMetadataEntity idpEntity, SamlSpConfigurationEntity spConfigEntity, String persistentId,
public SamlUserEntity preCreateUser(SamlIdpMetadataEntity idpEntity, SamlSpConfigurationEntity spConfigEntity, SamlIdentifier samlIdentifier,
String locale, Map<String, List<Object>> attributeMap)
throws UserUpdateException {
logger.debug("User {} from {} is being preCreated", persistentId, idpEntity.getEntityId());
logger.debug("User ({},{},{}) from {} is being preCreated", samlIdentifier.getPersistentId(),
samlIdentifier.getPairwiseId(), samlIdentifier.getSubjectId(), idpEntity.getEntityId());
idpEntity = idpMetadataService.findById(idpEntity.getId());
SamlUserEntity entity = samlUserDao.createNew();
entity.setIdp(idpEntity);
entity.setPersistentSpId(spConfigEntity.getEntityId());
entity.setPersistentId(persistentId);
entity.setRoles(new HashSet<UserRoleEntity>());
entity.setAttributeStore(new HashMap<String, String>());
entity.setGenericStore(new HashMap<String, String>());
......@@ -106,7 +117,9 @@ public class UserCreateServiceImpl implements UserCreateService {
entity.setEppn(attrHelper.getSingleStringFirst(attributeMap, "urn:oid:1.3.6.1.4.1.5923.1.1.1.6"));
entity.setGivenName(attrHelper.getSingleStringFirst(attributeMap, "urn:oid:2.5.4.42"));
entity.setSurName(attrHelper.getSingleStringFirst(attributeMap, "urn:oid:2.5.4.4"));
saml2AssertionService.updateUserIdentifier(samlIdentifier, entity, spConfigEntity.getEntityId(), null);
return entity;
}
......
......@@ -561,15 +561,14 @@ public class UserLoginServiceImpl implements UserLoginService, Serializable {
Assertion assertion = saml2AssertionService.processSamlResponse(samlResponse, idp, idpEntityDescriptor, spEntity);
SamlIdentifier samlIdentifier = saml2AssertionService.extractPersistentId(idp, assertion, spEntity, null);
String persistentId = saml2AssertionService.resolveIdentifier(samlIdentifier, idp, null);
SamlUserEntity user = saml2AssertionService.resolveUser(samlIdentifier, idp, spEntity.getEntityId(), null);
SamlUserEntity user = samlUserDao.findByPersistent(spEntity.getEntityId(),
idp.getEntityId(), persistentId);
if (user == null) {
throw new UserNotRegisteredException("user not registered in webapp");
}
saml2AssertionService.updateUserIdentifier(samlIdentifier, user, spEntity.getEntityId(), null);
try {
user = userUpdater.updateUser(user, assertion, caller, service, null);
} catch (UserUpdateException e) {
......
......@@ -26,6 +26,7 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apache.commons.lang.NotImplementedException;
import org.opensaml.saml.common.SAMLObject;
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Attribute;
......@@ -53,8 +54,8 @@ import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.SamlIdpScopeEntity;
import edu.kit.scc.webreg.entity.SamlMetadataEntity;
import edu.kit.scc.webreg.entity.SamlSpConfigurationEntity;
import edu.kit.scc.webreg.entity.SamlUserEntity;
import edu.kit.scc.webreg.entity.ScriptEntity;
import edu.kit.scc.webreg.hook.UserUpdateHookException;
import edu.kit.scc.webreg.script.ScriptingEnv;
import edu.kit.scc.webreg.service.saml.exc.NoAssertionException;
import edu.kit.scc.webreg.service.saml.exc.SamlAuthenticationException;
......@@ -144,10 +145,10 @@ public class Saml2AssertionService {
return assertion;
}
public String resolveIdentifier(SamlIdentifier samlIdentifier, SamlIdpMetadataEntity idpEntity, StringBuffer debugLog)
public SamlUserEntity resolveUser(SamlIdentifier samlIdentifier, SamlIdpMetadataEntity idpEntity, String samlSpEntityId, StringBuffer debugLog)
throws SamlAuthenticationException {
if (idpEntity.getGenericStore().containsKey("extract_id_script")) {
String scriptName = idpEntity.getGenericStore().get("extract_id_script");
if (idpEntity.getGenericStore().containsKey("resolve_user_script")) {
String scriptName = idpEntity.getGenericStore().get("resolve_user_script");
ScriptEntity scriptEntity = scriptingEnv.getScriptDao().findByName(scriptName);
......@@ -159,9 +160,9 @@ public class Saml2AssertionService {
engine.eval(scriptEntity.getScript());
Invocable invocable = (Invocable) engine;
Object o = invocable.invokeFunction("extractId", scriptingEnv, samlIdentifier, logger, debugLog);
if (o != null) {
return o.toString();
Object o = invocable.invokeFunction("resolveUser", scriptingEnv, samlIdentifier, idpEntity, samlSpEntityId, logger, debugLog);
if ((o != null) && (o instanceof SamlUserEntity)) {
return (SamlUserEntity) o;
}
} catch (NoSuchMethodException | ScriptException e) {
logger.warn("Script execution failed", e);
......@@ -174,19 +175,54 @@ public class Saml2AssertionService {
* prefer pairwise-id over persistent over subject-id
*/
if (samlIdentifier.getPairwiseId() != null) {
return samlIdentifier.getPairwiseId();
return scriptingEnv.getSamlUserDao().findByPersistent(samlSpEntityId, idpEntity.getEntityId(), samlIdentifier.getPairwiseId());
}
else if (samlIdentifier.getPersistentId() != null) {
return samlIdentifier.getPersistentId();
return scriptingEnv.getSamlUserDao().findByPersistent(samlSpEntityId, idpEntity.getEntityId(), samlIdentifier.getPersistentId());
}
else if (samlIdentifier.getSubjectId() != null) {
return samlIdentifier.getSubjectId();
throw new NotImplementedException("Not implemented yet");
}
else {
throw new SamlAuthenticationException("No usable identifier found. Acceptable identifiers are Pairwise-ID, Subject-ID or Persistent ID");
}
}
public void updateUserIdentifier(SamlIdentifier samlIdentifier, SamlUserEntity user, String samlSpEntityId, StringBuffer debugLog) {
if (user.getIdp().getGenericStore().containsKey("resolve_user_script")) {
String scriptName = user.getIdp().getGenericStore().get("resolve_user_script");
ScriptEntity scriptEntity = scriptingEnv.getScriptDao().findByName(scriptName);
if (scriptEntity != null && scriptEntity.getScriptType().equalsIgnoreCase("javascript")) {
ScriptEngine engine = (new ScriptEngineManager()).getEngineByName(scriptEntity.getScriptEngine());
if (engine != null) {
try {
engine.eval(scriptEntity.getScript());
Invocable invocable = (Invocable) engine;
invocable.invokeFunction("updateIdentifier", scriptingEnv, samlIdentifier, user, logger, debugLog);
} catch (NoSuchMethodException | ScriptException e) {
logger.warn("Script execution failed", e);
}
}
}
}
else {
if (samlIdentifier.getPairwiseId() != null) {
user.setPersistentId(samlIdentifier.getPairwiseId());
}
else if (samlIdentifier.getPersistentId() != null) {
user.setPersistentId(samlIdentifier.getPersistentId());
}
if (samlIdentifier.getSubjectId() != null) {
user.setSubjectId(samlIdentifier.getSubjectId());
}
}
}
public SamlIdentifier extractPersistentId(SamlIdpMetadataEntity idpEntity, Assertion assertion, SamlSpConfigurationEntity spEntity, StringBuffer debugLog)
throws IOException, DecryptionException, SamlAuthenticationException {
logger.debug("Fetching name Id from assertion");
......
......@@ -114,11 +114,14 @@ public class SamlSpPostServiceImpl implements SamlSpPostService {
}
samlIdentifier = saml2AssertionService.extractPersistentId(idpEntity, assertion, spConfig, debugLog);
persistentId = saml2AssertionService.resolveIdentifier(samlIdentifier, idpEntity, debugLog);
if (debugLog != null) {
debugLog.append("Resulting Persistent NameID: ").append(persistentId).append("\n");
debugLog.append("Resulting IDs (persistent, pairwise, subject): (")
.append(samlIdentifier.getPersistentId()).append(", ")
.append(samlIdentifier.getPairwiseId()).append(", ")
.append(samlIdentifier.getSubjectId()).append(")\n");
}
} catch (Exception e1) {
/*
* Catch Exception here for a probably faulty IDP. Register Exception and rethrow.
......@@ -149,9 +152,8 @@ public class SamlSpPostServiceImpl implements SamlSpPostService {
Map<String, List<Object>> attributeMap = saml2AssertionService.extractAttributes(assertion);
SamlUserEntity user = userDao.findByPersistent(spConfig.getEntityId(),
idpEntity.getEntityId(), persistentId);
SamlUserEntity user = saml2AssertionService.resolveUser(samlIdentifier, idpEntity, spConfig.getEntityId(), null);
if (user != null) {
MDC.put("userId", "" + user.getId());
}
......@@ -161,7 +163,7 @@ public class SamlSpPostServiceImpl implements SamlSpPostService {
// Store SAML Data temporarily in Session
logger.debug("Storing relevant SAML data in session");
session.setPersistentId(persistentId);
session.setSamlIdentifier(samlIdentifier);
session.setAttributeMap(attributeMap);
if (debugLog != null) {
......@@ -174,8 +176,10 @@ public class SamlSpPostServiceImpl implements SamlSpPostService {
}
}
logger.debug("Updating user {}", persistentId);
logger.debug("Updating user {}", user.getId());
saml2AssertionService.updateUserIdentifier(samlIdentifier, user, spConfig.getEntityId(), debugLog);
try {
user = userUpdater.updateUser(user, assertion, "web-sso");
} catch (UserUpdateException e) {
......
......@@ -25,6 +25,7 @@ import javax.inject.Named;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.RoleEntity;
import edu.kit.scc.webreg.entity.ServiceEntity;
import edu.kit.scc.webreg.service.saml.SamlIdentifier;
@Named("sessionManager")
@SessionScoped
......@@ -52,6 +53,7 @@ public class SessionManager implements Serializable {
private Long idpId;
private Long spId;
private String persistentId;
private SamlIdentifier samlIdentifier;
/*
* For Local logins to home org OIDC OP
......@@ -378,4 +380,12 @@ public class SessionManager implements Serializable {
public Set<Long> getLoggedInUserList() {
return loggedInUserList;
}
public SamlIdentifier getSamlIdentifier() {
return samlIdentifier;
}
public void setSamlIdentifier(SamlIdentifier samlIdentifier) {
this.samlIdentifier = samlIdentifier;
}
}
......@@ -85,7 +85,7 @@ public class RegisterUserBean implements Serializable {
spConfigEntity = spService.findById(sessionManager.getSpId());
try {
entity = userCreateService.preCreateUser(idpEntity, spConfigEntity, sessionManager.getPersistentId(),
entity = userCreateService.preCreateUser(idpEntity, spConfigEntity, sessionManager.getSamlIdentifier(),
sessionManager.getLocale(), sessionManager.getAttributeMap());
} catch (UserUpdateException e) {
......
......@@ -40,6 +40,7 @@ import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.saml.AttributeQueryHelper;
import edu.kit.scc.webreg.service.saml.Saml2AssertionService;
import edu.kit.scc.webreg.service.saml.SamlHelper;
import edu.kit.scc.webreg.service.saml.SamlIdentifier;
@Named
@ViewScoped
......@@ -129,7 +130,8 @@ public class BulkUserImportBean implements Serializable {
try {
Map<String, List<Object>> attributeMap = new HashMap<String, List<Object>>();
userEntity = userCreateService.preCreateUser(idpEntity, spEntity, importUser.getPersistentId(), null, attributeMap);
userEntity = userCreateService.preCreateUser(idpEntity, spEntity,
new SamlIdentifier(importUser.getPersistentId(), null, null, null), null, attributeMap);
Response samlResponse = attrQueryHelper.query(userEntity, idpEntity, idpEntityDescriptor, spEntity);
......
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