diff options
8 files changed, 257 insertions, 22 deletions
diff --git a/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml b/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml index 8e210c040..563fd6ec7 100644 --- a/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml +++ b/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml @@ -27,5 +27,5 @@ </task:scheduled-tasks>
<bean id="authenticationManager" class="at.gv.egovernment.moa.id.moduls.AuthenticationManager" factory-method="getInstance" />
-
+ <bean id="moduleRegistration" class="at.gv.egovernment.moa.id.moduls.modulregistration.ModuleRegistration" factory-method="getInstance" />
</beans>
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GenerateIFrameTemplateServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GenerateIFrameTemplateServlet.java index 430936e97..6e817e2a5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GenerateIFrameTemplateServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GenerateIFrameTemplateServlet.java @@ -41,12 +41,15 @@ import at.gv.egovernment.moa.id.commons.db.dao.config.TemplateType; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.moduls.moduleregistration.ModuleRegistration; import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.FileUtils; import at.gv.egovernment.moa.util.MiscUtil; +import com.datentechnik.process_engine.ExecutionContextImpl; import com.datentechnik.process_engine.ProcessInstance; +import com.datentechnik.process_engine.api.ExecutionContext; public class GenerateIFrameTemplateServlet extends AuthServlet { @@ -144,16 +147,24 @@ public class GenerateIFrameTemplateServlet extends AuthServlet { moasession.getAction(), req); } - + + ExecutionContext ec = new ExecutionContextImpl(); + // set execution context + ec.put("ccc", moasession.getCcc()); + ec.put("useMandate", moasession.getUseMandate()); + ec.put("bkuURL", moasession.getBkuURL()); + // select and create process instance - // TODO[MOAID-49]: Automatically selection of process - ProcessInstance pi = getProcessEngine().createProcessInstance("DefaultAuthentication"); - // keep process instance id in moa session - moasession.setProcessInstanceId(pi.getId()); - // set execution context - pi.getExecutionContext().put("ccc", moasession.getCcc()); - pi.getExecutionContext().put("useMandate", moasession.getUseMandate()); - pi.getExecutionContext().put("bkuURL", moasession.getBkuURL()); + String processDefinitionId = ModuleRegistration.getInstance().selectProcess(ec); + ProcessInstance pi = getProcessEngine().createProcessInstance(processDefinitionId, ec); + + if (processDefinitionId == null) { + Logger.warn("No suitable process found for SessionID " + moasession.getSessionID()); + throw new MOAIDException("process.02", new Object[] { moasession.getSessionID() }); + } + + // keep process instance id in moa session + moasession.setProcessInstanceId(pi.getId()); // make sure moa session has been persisted before running the process try { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java index 0c481d94e..1a0c11aa1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java @@ -76,6 +76,7 @@ import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.SLOInformationContainer; import at.gv.egovernment.moa.id.data.SLOInformationImpl; +import at.gv.egovernment.moa.id.moduls.moduleregistration.ModuleRegistration; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder; import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding; @@ -94,9 +95,11 @@ import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; +import com.datentechnik.process_engine.ExecutionContextImpl; import com.datentechnik.process_engine.ProcessEngine; import com.datentechnik.process_engine.ProcessExecutionException; import com.datentechnik.process_engine.ProcessInstance; +import com.datentechnik.process_engine.api.ExecutionContext; public class AuthenticationManager implements MOAIDAuthConstants { @@ -544,13 +547,26 @@ public class AuthenticationManager implements MOAIDAuthConstants { Logger.info("Start Authentication Module: " + moasession.getModul() + " Action: " + moasession.getAction()); - + // create execution context + ExecutionContext executionContext = new ExecutionContextImpl(); + executionContext.put("ccc", moasession.getCcc()); + executionContext.put("useMandate", moasession.getUseMandate()); + executionContext.put("bkuURL", moasession.getBkuURL()); + executionContext.put(PARAM_SESSIONID, moasession.getSessionID()); + // create process instance - // TODO[MOAID-49]: Automatically selection of process - ProcessInstance pi = processEngine.createProcessInstance("DefaultAuthentication"); - // keep process instance id in moa session - moasession.setProcessInstanceId(pi.getId()); - + String processDefinitionId = ModuleRegistration.getInstance().selectProcess(executionContext); + + if (processDefinitionId == null) { + Logger.warn("No suitable process found for SessionID " + moasession.getSessionID() ); + throw new MOAIDException("process.02",new Object[] { + moasession.getSessionID()}); + } + + ProcessInstance pi = processEngine.createProcessInstance(processDefinitionId, executionContext); + // keep process instance id in moa session + moasession.setProcessInstanceId(pi.getId()); + // make sure moa session has been persisted before running the process try { AuthenticationSessionStoreage.storeSession(moasession); @@ -560,12 +576,6 @@ public class AuthenticationManager implements MOAIDAuthConstants { moasession.getSessionID()}); } - // set execution context - pi.getExecutionContext().put("ccc", moasession.getCcc()); - pi.getExecutionContext().put("useMandate", moasession.getUseMandate()); - pi.getExecutionContext().put("bkuURL", moasession.getBkuURL()); - pi.getExecutionContext().put(PARAM_SESSIONID, moasession.getSessionID()); - // start process processEngine.start(pi); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModule.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModule.java new file mode 100644 index 000000000..35273cd2b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModule.java @@ -0,0 +1,40 @@ +package at.gv.egovernment.moa.id.moduls.moduleregistration; + +import com.datentechnik.process_engine.api.ExecutionContext; +import com.datentechnik.process_engine.model.ProcessDefinition; + +/** + * Defines the module capabilities. + */ +public interface AuthModule { + + /** + * Returns the priority of the module. The priority defines the place in the + * order of modules. The module with a highest priority is asked first, if + * it has a process which can do an authentication. + * + * @return the priority of the module. + */ + int getPriority(); + + /** + * Checks if the module has a process, which is able to perform an authentication + * with the given {@link ExecutionContext}. + * + * @param context + * an ExecutionContext for a process. + * @return the process-ID of a process which is able to work with the given + * ExecutionContext, or {@code null}. + */ + String selectProcess(ExecutionContext context); + + /** + * Returns the an Array of {@link ProcessDefinition}s of the processes + * included in this module. + * + * @return an array of resource uris of the processes included in this + * module. + */ + String[] getProcessDefinitions(); + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModuleImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModuleImpl.java new file mode 100644 index 000000000..cbe5c5932 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModuleImpl.java @@ -0,0 +1,23 @@ +package at.gv.egovernment.moa.id.moduls.moduleregistration; + +import com.datentechnik.process_engine.api.ExecutionContext; + +public class AuthModuleImpl implements AuthModule { + + @Override + public int getPriority() { + // neutral priority between Integer.MIN_VALUE and Integer.MAX_VALUE + return 0; + } + + @Override + public String selectProcess(ExecutionContext context) { + return context.get("ccc") == null ? "DefaultAuthentication" : null; + } + + @Override + public String[] getProcessDefinitions() { + return new String[] { "DefaultAuthentication" }; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/ModuleRegistration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/ModuleRegistration.java new file mode 100644 index 000000000..b90e0d94f --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/ModuleRegistration.java @@ -0,0 +1,148 @@ +package at.gv.egovernment.moa.id.moduls.moduleregistration; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; + +import com.datentechnik.process_engine.ProcessDefinitionParserException; +import com.datentechnik.process_engine.ProcessEngine; +import com.datentechnik.process_engine.api.ExecutionContext; + +/** + * This class handles registering modules. The modules are detected either with + * the ServiceLoader mechanism or via Spring. All detected modules are ranked + * according to their priority. + */ +public class ModuleRegistration { + + private static ModuleRegistration instance = new ModuleRegistration(); + + private List<AuthModule> orderedModules = new ArrayList<>(); + + @Autowired + private ApplicationContext ctx; + + @Autowired + ProcessEngine processEngine; + + private Logger log = LoggerFactory.getLogger(getClass()); + + public static ModuleRegistration getInstance() { + return instance; + } + + private ModuleRegistration() { + } + + @PostConstruct + private void init() { + // load modules via the ServiceLoader + initServiceLoaderModules(); + + // load modules via Spring + initSpringModules(); + + // order modules according to their priority + orderModules(); + } + + /** + * Discovers modules which use the ServiceLoader mechanism. + */ + private void initServiceLoaderModules() { + log.debug("Discovering modules which use the ServiceLoader mechanism."); + ServiceLoader<AuthModule> loader = ServiceLoader.load(AuthModule.class); + Iterator<AuthModule> modules = loader.iterator(); + while (modules.hasNext()) { + AuthModule module = modules.next(); + registerResourceUris(module); + orderedModules.add(module); + } + } + + /** + * Discovers modules which use Spring. + */ + private void initSpringModules() { + log.debug("Discovering Spring modules."); + Map<String, AuthModule> modules = ctx.getBeansOfType(AuthModule.class); + for (AuthModule module : modules.values()) { + registerResourceUris(module); + orderedModules.add(module); + } + } + + /** + * Registers the resource uris for the module. + * + * @param module + * the module. + */ + private void registerResourceUris(AuthModule module) { + for (String uri : module.getProcessDefinitions()) { + Resource resource = ctx.getResource(uri); + if (resource.exists()) { + log.debug("Registering process definition resource uri: '{}'.", resource); + try (InputStream processDefinitionInputStream = resource.getInputStream()) { + processEngine.registerProcessDefinition(processDefinitionInputStream); + } catch (IOException e) { + log.info("Resource uri: '{}' could NOT be read.", resource); + } catch (ProcessDefinitionParserException e) { + log.warn("Error while parsing process definition in '{}'", resource); + } + } else { + log.info("Resource uri: '{}' does NOT exist.", resource); + } + } + } + + /** + * Order the modules in descending order according to their priority. + */ + private void orderModules() { + Collections.sort(orderedModules, new Comparator<AuthModule>() { + @Override + public int compare(AuthModule thisAuthModule, AuthModule otherAuthModule) { + int thisOrder = thisAuthModule.getPriority(); + int otherOrder = otherAuthModule.getPriority(); + return (thisOrder < otherOrder ? -1 : (thisOrder == otherOrder ? 0 : 1)); + } + }); + log.debug("Modules are ordered in descending order, according to their priority."); + } + + /** + * Returns the process id of the first process, in the highest ranked + * module, which is able to work with the given execution context. + * + * @param context + * the {@link ExecutionContext}. + * @return the process id or {@code null} + */ + public String selectProcess(ExecutionContext context) { + for (AuthModule module : orderedModules) { + String id = module.selectProcess(context); + if (StringUtils.isNotEmpty(id)) { + log.debug("Process with id '{}' selected, for context '{}'.", id, context); + return id; + } + } + log.info("No process is able to handle context '{}'.", context); + return null; + } +} diff --git a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.modulregistration.AuthModule b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.modulregistration.AuthModule new file mode 100644 index 000000000..0d7e98006 --- /dev/null +++ b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.modulregistration.AuthModule @@ -0,0 +1,2 @@ +# The default moaid process +at.gv.egovernment.moa.id.moduls.modulregistration.AuthModuleImpl
\ No newline at end of file diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index 8807d4ce0..ad01644a1 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -272,3 +272,4 @@ slo.01=Sie konnten NICHT erfolgreich von allen Online-Applikationen abgemeldet w slo.02=Es wurde keine aktive SSO Session gefunden oder Sie sind bei keiner Online-Applikation angemeldet.
process.01=Fehler beim Ausf\u00FChren des Prozesses.
+process.02=Fehler beim Erstellen eines geeigneten Prozesses f\u00FCr die SessionID {0}.
|