From 44b9f57e478cd16ea28137d2aee60de7629f9f4d Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Thu, 4 Apr 2013 14:38:32 +0200 Subject: added SAML1 Protocol simple implementation added Loginform builder added login confirmation builder added login form template added modul logic added entrypoints --- .../id/auth/builder/LoginConfirmationBuilder.java | 79 ++++++ .../moa/id/auth/builder/LoginFormBuilder.java | 47 ++++ .../id/auth/servlet/VerifyIdentityLinkServlet.java | 5 +- .../moa/id/entrypoints/AuthDispatcherServlet.java | 219 +++++++++++++++ .../moa/id/entrypoints/DispatcherServlet.java | 192 ++++++++++++++ .../moa/id/moduls/AuthenticationManager.java | 73 +++++ .../moa/id/moduls/AuthenticationSessionStore.java | 75 ++++++ .../gv/egovernment/moa/id/moduls/IModulInfo.java | 19 ++ .../moa/id/moduls/ITargetConfiguration.java | 5 + .../gv/egovernment/moa/id/moduls/ModulStorage.java | 51 ++++ .../gv/egovernment/moa/id/moduls/ServletInfo.java | 31 +++ .../gv/egovernment/moa/id/moduls/ServletType.java | 5 + .../moa/id/moduls/TargetConfigurationImpl.java | 15 ++ .../moa/id/protocols/saml1/GetArtifactServlet.java | 118 +++++++++ .../saml1/GetAuthenticationDataService.java | 164 ++++++++++++ .../protocols/saml1/SAML1AuthenticationServer.java | 295 +++++++++++++++++++++ .../moa/id/protocols/saml1/SAML1Protocol.java | 78 ++++++ .../egovernment/moa/id/util/HTTPSessionUtils.java | 41 +++ .../resources/resources/templates/loginForm.html | 55 ++++ 19 files changed, 1565 insertions(+), 2 deletions(-) create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginConfirmationBuilder.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/AuthDispatcherServlet.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IModulInfo.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ITargetConfiguration.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletInfo.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletType.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/TargetConfigurationImpl.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactServlet.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPSessionUtils.java create mode 100644 id/server/idserverlib/src/main/resources/resources/templates/loginForm.html (limited to 'id') diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginConfirmationBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginConfirmationBuilder.java new file mode 100644 index 000000000..69e654f56 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginConfirmationBuilder.java @@ -0,0 +1,79 @@ +package at.gv.egovernment.moa.id.auth.builder; + + +public class LoginConfirmationBuilder { + /** private static String NL contains the NewLine representation in Java*/ + private static final String nl = "\n"; + + private static final String OA_URL_TAG = ""; + private static final String FORM_METHOD_TAG = ""; + private static final String ATTR_NAME_TAG = ""; + private static final String ATTR_VALUE_TAG = ""; + private static final String ATTR_TEMP_TAG = ""; + private static final String OA_TAG = ""; + private static final String NAME_TAG = ""; + + private static final String METHOD_GET = "GET"; + private static final String METHOD_POST = "POST"; + + + private static final String ATTR_TEMPLATE = + " " + nl; + + /** default HTML template */ + private static final String DEFAULT_HTML_TEMPLATE = + "" + nl + + "" + nl + + "" + nl + + "Anmeldung mit Bürgerkarte" + nl + + "" + nl + + "" + nl + + "

Wollen Sie sich als "+NAME_TAG+" bei "+OA_TAG+ + " anmelden?

" + nl + + "
" + nl + + ATTR_TEMP_TAG + + " " + nl + + "
" + nl + + "" + nl + + ""; + + private String template; + + public LoginConfirmationBuilder(){ + init(METHOD_GET); + } + + public LoginConfirmationBuilder(String method) { + init(method); + } + + public void init(String method) { + if(method.equals(METHOD_POST)) { + template = DEFAULT_HTML_TEMPLATE.replace(FORM_METHOD_TAG, METHOD_POST); + } else { + template = DEFAULT_HTML_TEMPLATE.replace(FORM_METHOD_TAG, METHOD_GET); + } + } + + public void addParameter(String name, String value) { + String attr_template = ATTR_TEMPLATE + ATTR_TEMP_TAG; + //Logger.info("Attr Template: " + attr_template); + attr_template = attr_template.replace(ATTR_NAME_TAG, name); + //Logger.info("Attr Template: " + attr_template); + attr_template = attr_template.replace(ATTR_VALUE_TAG, value); + //Logger.info("Attr Template: " + attr_template); + template = template.replace(ATTR_TEMP_TAG, attr_template); + //Logger.info("Template: " + template); + } + + public String finish(String oaURL, String userName, String oa) { + template = template.replace(NAME_TAG, userName); + template = template.replace(OA_TAG, oa); + template = template.replace(OA_URL_TAG, oaURL); + return template.replace(ATTR_TEMP_TAG, ""); + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java new file mode 100644 index 000000000..6816c854e --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginFormBuilder.java @@ -0,0 +1,47 @@ +package at.gv.egovernment.moa.id.auth.builder; + +import java.io.InputStream; +import java.io.StringWriter; + +import org.apache.commons.io.IOUtils; + +import at.gv.egovernment.moa.logging.Logger; + +public class LoginFormBuilder { + + private static String AUTH_URL = "#AUTH_URL#"; + private static String OA_URL = "#OA_URL#"; + private static String RED_URL = "#RED_URL#"; + + private static String template; + + private static String getTemplate() { + + if (template == null) { + try { + String classpathLocation = "resources/templates/loginForm.html"; + InputStream input = Thread.currentThread() + .getContextClassLoader() + .getResourceAsStream(classpathLocation); + StringWriter writer = new StringWriter(); + IOUtils.copy(input, writer); + template = writer.toString(); + template = template.replace(AUTH_URL, "StartBKUAuthentication"); + } catch (Exception e) { + Logger.error("Failed to read template", e); + } + } + + return template; + } + + public static String buildLoginForm(String oaURL) { + String value = getTemplate(); + + if(value != null) { + value = value.replace(OA_URL, oaURL); + } + return value; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java index 5178e27d3..61b55f73d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java @@ -150,7 +150,7 @@ public class VerifyIdentityLinkServlet extends AuthServlet { try { - Logger.debug("Send InfoboxReadRequest to BKU to get signer certificate."); + Logger.info("Send InfoboxReadRequest to BKU to get signer certificate."); // create the InfoboxReadRequest to get the certificate String infoboxReadRequest = new InfoboxReadRequestBuilderCertificate().build(true); @@ -174,7 +174,7 @@ public class VerifyIdentityLinkServlet extends AuthServlet { } else { // @TODO: unteren InfoboxReadRequest zu, Signer-Cert auslesen (wegen Cert Abfrage auf Organwalter OID), - // nach oben verschoben vor verifyIdentityLink (da hier schon bPK berechnet, die aber fr OW nicht in + // nach oben verschoben vor verifyIdentityLink (da hier schon bPK berechnet, die aber f�r OW nicht in // AUTH Block aufscheinen darf. --> D.h. verifyIdentityLink umbauen - verify und AUTH Block bauen trennen) boolean useMandate = session.getUseMandate(); if (useMandate) { // Mandate modus @@ -199,6 +199,7 @@ public class VerifyIdentityLinkServlet extends AuthServlet { } else { + Logger.info("Normal"); ServletUtils.writeCreateXMLSignatureRequestOrRedirect(resp, session, createXMLSignatureRequestOrRedirect, AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, "VerifyIdentityLink"); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/AuthDispatcherServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/AuthDispatcherServlet.java new file mode 100644 index 000000000..e78d9345c --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/AuthDispatcherServlet.java @@ -0,0 +1,219 @@ +package at.gv.egovernment.moa.id.entrypoints; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthInitializer; +import at.gv.egovernment.moa.id.moduls.AuthenticationManager; +import at.gv.egovernment.moa.id.moduls.IModulInfo; +import at.gv.egovernment.moa.id.moduls.ITargetConfiguration; +import at.gv.egovernment.moa.id.moduls.ModulStorage; +import at.gv.egovernment.moa.id.moduls.ServletInfo; +import at.gv.egovernment.moa.id.moduls.ServletType; +import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.logging.Logger; + +public class AuthDispatcherServlet extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public static final String PARAM_TARGET_PATH = "mod"; + public static final String PARAM_TARGET_PROTOCOL = "action"; + public static final String PARAM_DISPATCHER_TARGETS = "DispatcherTargets"; + public static final String PARAM_DISPATCHER_TYPE = "DispatcherType"; + public static final String PARAM_DISPATCHER_TYPE_UNAUTH = "UNAUTH"; + public static final String PARAM_DISPATCHER_TYPE_AUTH = "AUTH"; + public static String SYSTEM_NEWLINE = System.getProperty("line.separator"); + + private HashMap> endpointMap = new HashMap>(); + + private void registerModule(IModulInfo modulInfo) { + + HashMap tempMap = new HashMap(); + + try { + + String path = modulInfo.getPath(); + + if (path == null) { + throw new Exception(String.format( + "%s does not return a valid target path!", + new Object[] { modulInfo.getClass().getName() })); + } + + Logger.debug("Registering: " + modulInfo.getName() + " under " + + path); + + List servletInfos = modulInfo.getServlets(); + + Iterator servletInfoIterator = servletInfos.iterator(); + + while (servletInfoIterator.hasNext()) { + + ServletInfo servletInfo = servletInfoIterator.next(); + + if (servletInfo.getType() == ServletType.AUTH) { + HttpServlet servlet = servletInfo.getServletInstance(); + String target = servletInfo.getTarget(); + + if (target == null) { + throw new Exception( + String.format( + "%s does not return a valid target identifier!", + new Object[] { servlet.getClass() + .getName() })); + } + + if (tempMap.containsKey(target)) { + throw new Exception(String.format( + "%s tried to overwrite %s/%s", new Object[] { + servlet.getClass().getName(), path, + target })); + } + + tempMap.put(target, servlet); + Logger.info("Registered Servlet class: " + + servlet.getClass().getName() + " OK"); + } + + } + + // when there was no error we register all servlets into the real + // endpoint map ... + if (!tempMap.isEmpty()) { + endpointMap.put(path, tempMap); + } + } catch (Throwable e) { + Logger.error("Registering Modul class: " + + modulInfo.getClass().getName() + " FAILED!!", e); + } + } + + @Override + public void init(ServletConfig config) throws ServletException { + try { + super.init(config); + MOAIDAuthInitializer.initialize(); + Logger.info(MOAIDMessageProvider.getInstance().getMessage( + "init.00", null)); + } catch (Exception ex) { + Logger.fatal( + MOAIDMessageProvider.getInstance().getMessage("init.02", + null), ex); + throw new ServletException(ex); + } + Logger.info("Auth dispatcher Servlet initialization"); + + List modules = ModulStorage.getAllModules(); + Iterator it = modules.iterator(); + while (it.hasNext()) { + IModulInfo info = it.next(); + String targetClass = info.getClass().getName(); + try { + registerModule(info); + } catch (Throwable e) { + Logger.error("Registering Class " + targetClass + " FAILED!!", + e); + } + } + } + + protected void processRequest(HttpServletRequest req, + HttpServletResponse resp) throws ServletException, IOException { + try { + Object pathObject = req.getAttribute(PARAM_TARGET_PATH); + String path = null; + + HttpSession session = req.getSession(); + + if (pathObject != null && (pathObject instanceof String)) { + path = (String) pathObject; + } + + if (path == null) { + path = (String) session.getAttribute(PARAM_TARGET_PATH); + } + + Object protocolObject = req.getAttribute(PARAM_TARGET_PROTOCOL); + String protocol = null; + if (protocolObject != null && (protocolObject instanceof String)) { + protocol = (String) protocolObject; + } + + if (protocol == null) { + protocol = (String) session.getAttribute(PARAM_TARGET_PROTOCOL); + } + + Logger.debug("dispatching to " + path + " protocol " + protocol); + + if (path != null && protocol != null + && endpointMap.containsKey(path)) { + IModulInfo info = ModulStorage.getModuleByPath(path); + if (info == null) { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + Logger.error("Path " + path + " has no module registered"); + return; + } + + ITargetConfiguration configuration = info.preProcess(req, resp); + + if (!AuthenticationManager.isAuthenticated(req, resp)) { + + session.setAttribute(PARAM_TARGET_PATH, path); + session.setAttribute(PARAM_TARGET_PROTOCOL, protocol); + + AuthenticationManager.doAuthentication(req, resp, + configuration); + return; + } + + HashMap pathMap = endpointMap.get(path); + Logger.debug("found path"); + if (pathMap.containsKey(protocol)) { + Logger.debug("found protocol"); + try { + HttpServlet servlet = (HttpServlet) pathMap + .get(protocol); + String forward = servlet.getClass().getName(); + Logger.info("Forwarding to Servlet: " + forward); + getServletContext().getNamedDispatcher(forward) + .forward(req, resp); + return; + } catch (Throwable e) { + e.printStackTrace(); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + } + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } catch (Throwable e) { + e.printStackTrace(); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + processRequest(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + processRequest(req, resp); + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java new file mode 100644 index 000000000..ccc0f1ccc --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/entrypoints/DispatcherServlet.java @@ -0,0 +1,192 @@ +package at.gv.egovernment.moa.id.entrypoints; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthInitializer; +import at.gv.egovernment.moa.id.moduls.IModulInfo; +import at.gv.egovernment.moa.id.moduls.ModulStorage; +import at.gv.egovernment.moa.id.moduls.ServletInfo; +import at.gv.egovernment.moa.id.moduls.ServletType; +import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.logging.Logger; + +public class DispatcherServlet extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public static final String PARAM_TARGET_PATH = "mod"; + public static final String PARAM_TARGET_PROTOCOL = "action"; + public static final String PARAM_DISPATCHER_TARGETS = "DispatcherTargets"; + public static final String PARAM_DISPATCHER_TYPE = "DispatcherType"; + public static final String PARAM_DISPATCHER_TYPE_UNAUTH = "UNAUTH"; + public static final String PARAM_DISPATCHER_TYPE_AUTH = "AUTH"; + public static String SYSTEM_NEWLINE = System.getProperty("line.separator"); + + private HashMap> endpointMap = new HashMap>(); + + private void registerModule(IModulInfo modulInfo) { + + HashMap tempMap = new HashMap(); + + try { + + String path = modulInfo.getPath(); + + if (path == null) { + throw new Exception(String.format( + "%s does not return a valid target path!", + new Object[] { modulInfo.getClass().getName() })); + } + + Logger.debug("Registering: " + modulInfo.getName() + " under " + + path); + + List servletInfos = modulInfo.getServlets(); + + Iterator servletInfoIterator = servletInfos.iterator(); + + while (servletInfoIterator.hasNext()) { + + ServletInfo servletInfo = servletInfoIterator.next(); + + if (servletInfo.getType() == ServletType.UNAUTH) { + HttpServlet servlet = servletInfo.getServletInstance(); + String target = servletInfo.getTarget(); + + if (target == null) { + throw new Exception( + String.format( + "%s does not return a valid target identifier!", + new Object[] { servlet.getClass() + .getName() })); + } + + if (tempMap.containsKey(target)) { + throw new Exception(String.format( + "%s tried to overwrite %s/%s", new Object[] { + servlet.getClass().getName(), path, + target })); + } + + tempMap.put(target, servlet); + Logger.info("Registered Servlet class: " + + servlet.getClass().getName() + " OK"); + } + + } + + // when there was no error we register all servlets into the real + // endpoint map ... + if (!tempMap.isEmpty()) { + endpointMap.put(path, tempMap); + } + } catch (Throwable e) { + Logger.error("Registering Modul class: " + + modulInfo.getClass().getName() + " FAILED!!", e); + } + } + + @Override + public void init(ServletConfig config) throws ServletException { + try { + super.init(config); + MOAIDAuthInitializer.initialize(); + Logger.info(MOAIDMessageProvider.getInstance().getMessage( + "init.00", null)); + } catch (Exception ex) { + Logger.fatal( + MOAIDMessageProvider.getInstance().getMessage("init.02", + null), ex); + throw new ServletException(ex); + } + Logger.info("Dispatcher Servlet initialization"); + + List modules = ModulStorage.getAllModules(); + Iterator it = modules.iterator(); + while (it.hasNext()) { + IModulInfo info = it.next(); + String targetClass = info.getClass().getName(); + try { + registerModule(info); + } catch (Throwable e) { + Logger.error("Registering Class " + targetClass + " FAILED!!", + e); + } + } + } + + protected void processRequest(HttpServletRequest req, + HttpServletResponse resp) throws ServletException, IOException { + Object pathObject = req.getAttribute(PARAM_TARGET_PATH); + String path = null; + if (pathObject != null && (pathObject instanceof String)) { + path = (String) pathObject; + } + + if (path == null) { + path = (String) req.getAttribute(PARAM_TARGET_PATH); + } + + Object protocolObject = req.getAttribute(PARAM_TARGET_PROTOCOL); + String protocol = null; + if (protocolObject != null && (protocolObject instanceof String)) { + protocol = (String) protocolObject; + } + + if (protocol == null) { + protocol = req.getParameter(PARAM_TARGET_PROTOCOL); + } + + Logger.debug("dispatching to " + path + " protocol " + protocol); + + if (path != null && protocol != null && endpointMap.containsKey(path)) { + HashMap pathMap = endpointMap.get(path); + Logger.debug("found path"); + if (pathMap.containsKey(protocol)) { + Logger.debug("found protocol"); + try { + HttpServlet servlet = (HttpServlet) pathMap.get(protocol); + String forward = servlet.getClass().getName(); + Logger.info("Forwarding to Servlet: " + forward); + getServletContext().getNamedDispatcher(forward).forward( + req, resp); + return; + } catch (Throwable e) { + Logger.error("Failed to process request!", e); + IModulInfo info = ModulStorage.getModuleByPath(path); + if(info != null) { + if(info.generateErrorMessage(e, req, resp)) { + return; + } + } + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + } + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + processRequest(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + processRequest(req, resp); + } +} 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 new file mode 100644 index 000000000..e631523a2 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java @@ -0,0 +1,73 @@ +package at.gv.egovernment.moa.id.moduls; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.builder.LoginFormBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.util.HTTPSessionUtils; +import at.gv.egovernment.moa.logging.Logger; + +public class AuthenticationManager implements MOAIDAuthConstants { + + public static final String MOA_SESSION = "MoaAuthenticationSession"; + public static final String MOA_AUTHENTICATED = "MoaAuthenticated"; + + public static AuthenticationSession getAuthenticationSession(HttpSession session) { + String sessionID = HTTPSessionUtils.getHTTPSessionString(session, MOA_SESSION, null); + if(sessionID != null) { + return AuthenticationSessionStore.getSession(sessionID); + } + return null; + } + + /** + * Checks if the session is authenticated + * @param request + * @param response + * @return + */ + public static boolean isAuthenticated(HttpServletRequest request, HttpServletResponse response) { + Logger.info("Checking authentication"); + + HttpSession session = request.getSession(); + + String sessionID = (String)request.getAttribute(PARAM_SESSIONID); + if(sessionID != null) { + AuthenticationSession authSession = AuthenticationSessionStore.getSession(sessionID); + if(authSession != null) { + if(authSession.isAuthenticated() && !authSession.isAuthenticatedUsed()) { + session.invalidate(); + session = request.getSession(); + HTTPSessionUtils.setHTTPSessionBoolean(session, MOA_AUTHENTICATED, true); + authSession.setAuthenticatedUsed(true); + HTTPSessionUtils.setHTTPSessionString(session, MOA_SESSION, sessionID); + } + } + } + + return HTTPSessionUtils.getHTTPSessionBoolean(session, MOA_AUTHENTICATED, false); + } + + public static void doAuthentication(HttpServletRequest request, HttpServletResponse response, + ITargetConfiguration target) + throws ServletException, IOException { + HttpSession session = request.getSession(); + Logger.info("Starting authentication ..."); + String loginForm = LoginFormBuilder.buildLoginForm(target.getOAURL()); + + response.setContentType("text/html;charset=UTF-8"); + PrintWriter out = new PrintWriter(response.getOutputStream()); + out.print(loginForm); + out.flush(); + return; + // TODO: Build authentication form + //session.getServletContext().getNamedDispatcher("StartAuthenticationServlet").forward(request, response); + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java new file mode 100644 index 000000000..c0bf29844 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java @@ -0,0 +1,75 @@ +package at.gv.egovernment.moa.id.moduls; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import at.gv.egovernment.moa.id.MOAIDException; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.util.Random; +import at.gv.egovernment.moa.logging.Logger; + +public class AuthenticationSessionStore { + + private static HashMap sessionStore = new HashMap(); + + public static boolean isAuthenticated(String moaSessionID) { + synchronized (sessionStore) { + if (sessionStore.containsKey(moaSessionID)) { + return sessionStore.get(moaSessionID).isAuthenticated(); + } + } + return false; + } + + public static AuthenticationSession createSession() { + String id = Random.nextRandom(); + AuthenticationSession session = new AuthenticationSession(id); + synchronized (sessionStore) { + sessionStore.put(id, session); + } + return session; + } + + public static void dumpSessionStore() { + synchronized (sessionStore) { + Set keys = sessionStore.keySet(); + Iterator keyIterator = keys.iterator(); + while(keyIterator.hasNext()) { + String key = keyIterator.next(); + AuthenticationSession session = sessionStore.get(key); + Logger.info("Key: " + key + " -> " + session.toString()); + } + } + } + + public static String changeSessionID(AuthenticationSession session) + throws MOAIDException { + synchronized (sessionStore) { + if (sessionStore.containsKey(session.getSessionID())) { + AuthenticationSession theSession = sessionStore.get(session + .getSessionID()); + if (theSession != session) { + throw new MOAIDException("TODO!", null); + } + + sessionStore.remove(session.getSessionID()); + String id = Random.nextRandom(); + session.setSessionID(id); + sessionStore.put(id, session); + return id; + } + } + throw new MOAIDException("TODO!", null); + } + + public static AuthenticationSession getSession(String sessionID) { + synchronized (sessionStore) { + if (sessionStore.containsKey(sessionID)) { + return sessionStore.get(sessionID); + } + } + Logger.info("No MOA Session with id: " + sessionID); + return null; + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IModulInfo.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IModulInfo.java new file mode 100644 index 000000000..1f51feff6 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/IModulInfo.java @@ -0,0 +1,19 @@ +package at.gv.egovernment.moa.id.moduls; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.MOAIDException; + +public interface IModulInfo { + public List getServlets(); + public String getName(); + public String getPath(); + + public ITargetConfiguration preProcess(HttpServletRequest request, HttpServletResponse response) + throws MOAIDException; + + public boolean generateErrorMessage(Throwable e,HttpServletRequest request, HttpServletResponse response); +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ITargetConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ITargetConfiguration.java new file mode 100644 index 000000000..e86f20496 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ITargetConfiguration.java @@ -0,0 +1,5 @@ +package at.gv.egovernment.moa.id.moduls; + +public interface ITargetConfiguration { + public String getOAURL(); +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java new file mode 100644 index 000000000..8b13bf9a1 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ModulStorage.java @@ -0,0 +1,51 @@ +package at.gv.egovernment.moa.id.moduls; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import at.gv.egovernment.moa.logging.Logger; + +public class ModulStorage { + + private static final String[] modulClasses = new String[]{ + "at.gv.egovernment.moa.id.protocols.saml1.SAML1Protocol" + }; + + + private static List registeredModules = new ArrayList(); + + public static List getAllModules() { + return registeredModules; + } + + public static IModulInfo getModuleByPath(String modname) { + Iterator it = registeredModules.iterator(); + while (it.hasNext()) { + IModulInfo info = it.next(); + if (info.getPath().equals(modname)) { + return info; + } + } + return null; + } + + static { + Logger.info("Loading modules:"); + for(int i = 0; i < modulClasses.length; i++) { + String modulClassName = modulClasses[i]; + try { + @SuppressWarnings("unchecked") + Class moduleClass = (Class)Class.forName(modulClassName); + IModulInfo module = moduleClass.newInstance(); + Logger.info("Loading Modul Information: " + module.getName()); + registeredModules.add(module); + } catch(Throwable e) { + Logger.error("Check configuration! " + modulClassName + + " is not a valid IModulInfo", e); + } + } + Logger.info("Loading modules done"); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletInfo.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletInfo.java new file mode 100644 index 000000000..0181233d5 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletInfo.java @@ -0,0 +1,31 @@ +package at.gv.egovernment.moa.id.moduls; + +import javax.servlet.http.HttpServlet; + + +public class ServletInfo { + Class servletClass; + String servletTarget; + ServletType type; + + public ServletInfo(Class servletClass, + String servletTarget, ServletType type) { + super(); + this.servletClass = servletClass; + this.servletTarget = servletTarget; + this.type = type; + } + + public HttpServlet getServletInstance() + throws InstantiationException, IllegalAccessException { + return servletClass.newInstance(); + } + + public String getTarget() { + return servletTarget; + } + + public ServletType getType() { + return type; + } +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletType.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletType.java new file mode 100644 index 000000000..50b1702f8 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/ServletType.java @@ -0,0 +1,5 @@ +package at.gv.egovernment.moa.id.moduls; + +public enum ServletType { + UNAUTH, AUTH, NONE +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/TargetConfigurationImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/TargetConfigurationImpl.java new file mode 100644 index 000000000..fadedce0b --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/TargetConfigurationImpl.java @@ -0,0 +1,15 @@ +package at.gv.egovernment.moa.id.moduls; + +public class TargetConfigurationImpl implements ITargetConfiguration { + + private String oaURL; + + public void setOAURL(String value) { + oaURL = value; + } + + public String getOAURL() { + return oaURL; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactServlet.java new file mode 100644 index 000000000..4dc4a2b35 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactServlet.java @@ -0,0 +1,118 @@ +package at.gv.egovernment.moa.id.protocols.saml1; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringEscapeUtils; + +import at.gv.egovernment.moa.id.AuthenticationException; +import at.gv.egovernment.moa.id.BuildException; +import at.gv.egovernment.moa.id.auth.WrongParametersException; +import at.gv.egovernment.moa.id.auth.builder.LoginConfirmationBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.servlet.AuthServlet; +import at.gv.egovernment.moa.id.config.ConfigurationException; +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.AuthenticationManager; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; + +public class GetArtifactServlet extends AuthServlet { + + /** + * + */ + private static final long serialVersionUID = 3593264832041467899L; + + /** + * Constructor for GetArtifactServlet. + */ + public GetArtifactServlet() { + super(); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + HttpSession httpSession = req.getSession(); + + AuthenticationSession session = AuthenticationManager + .getAuthenticationSession(httpSession); + + String oaURL = (String) req.getAttribute(PARAM_OA); + oaURL = StringEscapeUtils.escapeHtml(oaURL); + + try { + + // check parameter + if (!ParamValidatorUtils.isValidOA(oaURL)) + throw new WrongParametersException("StartAuthentication", + PARAM_OA, "auth.12"); + + String samlArtifactBase64 = SAML1AuthenticationServer + .BuildSAMLArtifact(session); + + /* + * String redirectURL = oaURL;//session.getOAURLRequested(); if + * (!session.getBusinessService()) { redirectURL = + * addURLParameter(redirectURL, PARAM_TARGET, + * URLEncoder.encode(session.getTarget(), "UTF-8")); + * + * } redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, + * URLEncoder.encode(samlArtifactBase64, "UTF-8")); redirectURL = + * resp.encodeRedirectURL(redirectURL); + * + * resp.setContentType("text/html"); resp.setStatus(302); + * + * resp.addHeader("Location", redirectURL); + * Logger.debug("REDIRECT TO: " + redirectURL); + */ + + OAAuthParameter oaParam = + AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); + + String friendlyName = oaParam.getFriendlyName(); + if(friendlyName == null) { + friendlyName = oaURL; + } + + LoginConfirmationBuilder builder = new LoginConfirmationBuilder(); + builder.addParameter(PARAM_SAMLARTIFACT, + samlArtifactBase64); + String form = builder.finish(oaURL, session.getIdentityLink() + .getName(), friendlyName); + + resp.setContentType("text/html"); + + OutputStream out = resp.getOutputStream(); + out.write(form.getBytes("UTF-8")); + out.flush(); + out.close(); + + } catch (WrongParametersException ex) { + handleWrongParameters(ex, req, resp); + } catch (ConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BuildException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (AuthenticationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + doGet(req, resp); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java new file mode 100644 index 000000000..3a9b79163 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetAuthenticationDataService.java @@ -0,0 +1,164 @@ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.protocols.saml1; + +import java.util.Calendar; + +import org.apache.axis.AxisFault; +import org.w3c.dom.Element; + +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.id.AuthenticationException; +import at.gv.egovernment.moa.id.MOAIDException; +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.builder.SAMLResponseBuilder; +import at.gv.egovernment.moa.id.data.AuthenticationData; +import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.id.util.Random; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.DateTimeUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * Web service for picking up authentication data created in the MOA-ID Auth component. + * + * @author Paul Ivancsics + * @version $Id: GetAuthenticationDataService.java 1233 2012-01-26 21:59:33Z kstranacher $ + * @see at.gv.egovernment.moa.id.auth.AuthenticationServer#getAuthenticationData + */ +public class GetAuthenticationDataService implements Constants { + + /** + * Constructor for GetAuthenticationDataService. + */ + public GetAuthenticationDataService() { + super(); + } + + /** + * Takes a lt;samlp:Request> containing a + * SAML artifact and returns the corresponding + * authentication data lt;saml:Assertion> + * (obtained from the AuthenticationServer), + * enclosed in a lt;samlp:Response>. + *
Bad requests are mapped into various lt;samlp:StatusCode>s, + * possibly containing enclosed sub-lt;samlp:StatusCode>s. + * The status codes are defined in the SAML specification. + * + * @param requests request elements of type lt;samlp:Request>; + * only 1 request element is allowed + * @return response element of type lt;samlp:Response>, + * packed into an Element[] + * @throws AxisFault thrown when an error occurs in assembling the + * lt;samlp:Response> + */ + public Element[] Request(Element[] requests) + throws AxisFault { + + Element request = requests[0]; + Element[] responses = new Element[1]; + String requestID = ""; + String statusCode = ""; + String subStatusCode = null; + String statusMessageCode = null; + String statusMessage = null; + String samlAssertion = ""; + boolean useUTC = false; + if (requests.length > 1) { + // more than 1 request given as parameter + statusCode = "samlp:Requester"; + subStatusCode = "samlp:TooManyResponses"; + statusMessageCode = "1201"; + } + else { + try { + DOMUtils.validateElement(request, ALL_SCHEMA_LOCATIONS, null); + NodeList samlArtifactList = XPathUtils.selectNodeList(request, "samlp:AssertionArtifact"); + if (samlArtifactList.getLength() == 0) { + // no SAML artifact given in request + statusCode = "samlp:Requester"; + statusMessageCode = "1202"; + } + else if (samlArtifactList.getLength() > 1) { + // too many SAML artifacts given in request + statusCode = "samlp:Requester"; + subStatusCode = "samlp:TooManyResponses"; + statusMessageCode = "1203"; + } + else { + Element samlArtifactElem = (Element)samlArtifactList.item(0); + requestID = request.getAttribute("RequestID"); + String samlArtifact = DOMUtils.getText(samlArtifactElem); + try { + + AuthenticationData authData = SAML1AuthenticationServer.getSaml1AuthenticationData(samlArtifact); + + useUTC = authData.getUseUTC(); + + // success + samlAssertion = authData.getSamlAssertion(); + statusCode = "samlp:Success"; + statusMessageCode = "1200"; + } + catch (AuthenticationException ex) { + // no authentication data for given SAML artifact + statusCode = "samlp:Requester"; + subStatusCode = "samlp:ResourceNotRecognized"; + statusMessage = ex.toString(); + } + } + } + catch (Throwable t) { + // invalid request format + statusCode = "samlp:Requester"; + statusMessageCode = "1204"; + } + } + try { + String responseID = Random.nextRandom(); + String issueInstant = DateTimeUtils.buildDateTime(Calendar.getInstance(), useUTC); + if (statusMessage == null) + statusMessage = MOAIDMessageProvider.getInstance().getMessage(statusMessageCode, null); + responses[0] = new SAMLResponseBuilder().build( + responseID, requestID, issueInstant, statusCode, subStatusCode, statusMessage, samlAssertion); + + } + catch (MOAIDException e) { + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } + catch (Throwable t) { + MOAIDException e = new MOAIDException("1299", null, t); + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } + return responses; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java new file mode 100644 index 000000000..56d02b557 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java @@ -0,0 +1,295 @@ +package at.gv.egovernment.moa.id.protocols.saml1; + +import iaik.x509.X509Certificate; + +import java.io.File; +import java.io.IOException; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import at.gv.egovernment.moa.id.AuthenticationException; +import at.gv.egovernment.moa.id.BuildException; +import at.gv.egovernment.moa.id.ParseException; +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder; +import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; +import at.gv.egovernment.moa.id.auth.builder.PersonDataBuilder; +import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser; +import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; +import at.gv.egovernment.moa.id.config.ConfigurationException; +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.AuthenticationData; +import at.gv.egovernment.moa.id.util.Random; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DateTimeUtils; +import at.gv.egovernment.moa.util.StringUtils; + +public class SAML1AuthenticationServer extends AuthenticationServer { + + // TODO: for clustering we have to replicate this data to other servers + // We might need to introduce a openEJB to accomplish this + /** authentication data store (assertion handle -> AuthenticationData) */ + private static Map authenticationDataStore = new HashMap(); + + /** + * time out in milliseconds used by {@link cleanup} for authentication data + * store + */ + private static final long authDataTimeOut = 2 * 60 * 1000; // default 2 minutes + + private static AuthenticationData buildAuthenticationData( + AuthenticationSession session, + VerifyXMLSignatureResponse verifyXMLSigResp, boolean useUTC, boolean isForeigner) + throws ConfigurationException, BuildException { + + IdentityLink identityLink = session.getIdentityLink(); + AuthenticationData authData = new AuthenticationData(); + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + boolean businessService = oaParam.getBusinessService(); + authData.setMajorVersion(1); + authData.setMinorVersion(0); + authData.setAssertionID(Random.nextRandom()); + authData.setIssuer(session.getAuthURL()); + authData.setIssueInstant(DateTimeUtils.buildDateTime(Calendar + .getInstance(), useUTC)); + authData.setIdentificationType(identityLink.getIdentificationType()); + authData.setGivenName(identityLink.getGivenName()); + authData.setFamilyName(identityLink.getFamilyName()); + authData.setDateOfBirth(identityLink.getDateOfBirth()); + authData.setQualifiedCertificate(verifyXMLSigResp + .isQualifiedCertificate()); + authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); + authData.setPublicAuthorityCode(verifyXMLSigResp + .getPublicAuthorityCode()); + authData.setBkuURL(session.getBkuURL()); + authData.setUseUTC(oaParam.getUseUTC()); + boolean provideStammzahl = oaParam.getProvideStammzahl(); + if (provideStammzahl) { + authData.setIdentificationValue(identityLink + .getIdentificationValue()); + } + String prPerson = new PersonDataBuilder().build(identityLink, + provideStammzahl); + + try { + String signerCertificateBase64 = ""; + if (oaParam.getProvideCertifcate()) { + X509Certificate signerCertificate = verifyXMLSigResp + .getX509certificate(); + if (signerCertificate != null) { + signerCertificateBase64 = Base64Utils + .encode(signerCertificate.getEncoded()); + } else { + Logger + .info("\"provideCertificate\" is \"true\", but no signer certificate available"); + } + } + authData.setSignerCertificate(signerCertificateBase64); + if(!isForeigner) { + //we have Austrian citizen + if (businessService) { + authData.setWBPK(identityLink.getIdentificationValue()); + } else { + authData.setBPK(identityLink.getIdentificationValue()); + + // BZ.., calculation of bPK already before sending AUTHBlock + /* + * if(identityLink.getIdentificationType().equals(Constants. + * URN_PREFIX_BASEID)) { // only compute bPK if online + * application is a public service and we have the Stammzahl + * String bpkBase64 = new BPKBuilder().buildBPK( + * identityLink.getIdentificationValue(), session.getTarget()); + * authData.setBPK(bpkBase64); } + */ + + } + } else { + //we have foreigner, thus we have to calculate bPK and wbPK now (after receiving identity link from SZR-GW + if (businessService) { + //since we have foreigner, wbPK is not calculated in BKU + if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { + String wbpkBase64 = new BPKBuilder().buildWBPK(identityLink.getIdentificationValue(), session.getDomainIdentifier()); + authData.setWBPK(wbpkBase64); + } + + } else { + + if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { + // only compute bPK if online application is a public service and we have the Stammzahl + String bpkBase64 = new BPKBuilder().buildBPK(identityLink.getIdentificationValue(), session.getTarget()); + authData.setBPK(bpkBase64); + } + + + } + + } + String ilAssertion = oaParam.getProvideIdentityLink() ? identityLink + .getSerializedSamlAssertion() + : ""; + if (!oaParam.getProvideStammzahl()) { + ilAssertion = StringUtils.replaceAll(ilAssertion, identityLink + .getIdentificationValue(), ""); + } + String authBlock = oaParam.getProvideAuthBlock() ? session + .getAuthBlock() : ""; + + session.setAssertionAuthBlock(authBlock); + session.setAssertionAuthData(authData); + session.setAssertionBusinessService(businessService); + session.setAssertionIlAssertion(ilAssertion); + session.setAssertionPrPerson(prPerson); + session.setAssertionSignerCertificateBase64(signerCertificateBase64); + + return authData; + + } catch (Throwable ex) { + throw new BuildException("builder.00", new Object[] { + "AuthenticationData", ex.toString() }, ex); + } + } + + /** + * Retrieves AuthenticationData indexed by the SAML artifact. + * The AuthenticationData is deleted from the store upon end of + * this call. + * + * @return AuthenticationData + */ + public static AuthenticationData getSaml1AuthenticationData(String samlArtifact) + throws AuthenticationException { + String assertionHandle; + try { + assertionHandle = new SAMLArtifactParser(samlArtifact) + .parseAssertionHandle(); + } catch (ParseException ex) { + throw new AuthenticationException("1205", new Object[] { + samlArtifact, ex.toString() }); + } + AuthenticationData authData = null; + synchronized (authenticationDataStore) { + // System.out.println("assertionHandle: " + assertionHandle); + authData = (AuthenticationData) authenticationDataStore + .get(assertionHandle); + if (authData == null) { + Logger.error("Assertion not found for SAML Artifact: " + + samlArtifact); + throw new AuthenticationException("1206", + new Object[] { samlArtifact }); + } + boolean keepAssertion = false; + try { + String boolStr = AuthConfigurationProvider.getInstance() + .getGenericConfigurationParameter( + "AuthenticationServer.KeepAssertion"); + if (null != boolStr && boolStr.equalsIgnoreCase("true")) + keepAssertion = true;// Only allowed for debug purposes!!! + } catch (ConfigurationException ex) { + throw new AuthenticationException("1205", new Object[] { + samlArtifact, ex.toString() }); + } + if (!keepAssertion) { + authenticationDataStore.remove(assertionHandle); + } + } + long now = new Date().getTime(); + if (now - authData.getTimestamp().getTime() > authDataTimeOut) + throw new AuthenticationException("1207", + new Object[] { samlArtifact }); + Logger.debug("Assertion delivered for SAML Artifact: " + samlArtifact); + return authData; + } + + public static String BuildSAMLArtifact(AuthenticationSession session) throws ConfigurationException, BuildException, AuthenticationException { + + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance() + .getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + boolean useUTC = oaParam.getUseUTC(); + boolean useCondition = oaParam.getUseCondition(); + int conditionLength = oaParam.getConditionLength(); + + // builds authentication data and stores it together with a SAML + // artifact + AuthenticationData authData = buildAuthenticationData(session, session.getXMLVerifySignatureResponse(), + useUTC, false); + + String samlAssertion = new AuthenticationDataAssertionBuilder().build( + authData, session.getAssertionPrPerson(), + session.getAssertionAuthBlock(), + session.getAssertionIlAssertion(), session.getBkuURL(), + session.getAssertionSignerCertificateBase64(), + session.getAssertionBusinessService(), + session.getExtendedSAMLAttributesOA(), useCondition, + conditionLength); + authData.setSamlAssertion(samlAssertion); + + String assertionFile = AuthConfigurationProvider.getInstance() + .getGenericConfigurationParameter( + "AuthenticationServer.WriteAssertionToFile"); + if (!ParepUtils.isEmpty(assertionFile)) + try { + ParepUtils.saveStringToFile(samlAssertion, new File( + assertionFile)); + } catch (IOException e) { + throw new BuildException("builder.00", new Object[] { + "AuthenticationData", e.toString() }, e); + } + + String samlArtifact = new SAMLArtifactBuilder().build( + session.getAuthURL(), session.getSessionID(), + session.getSourceID()); + + storeAuthenticationData(samlArtifact, authData); + + Logger.info("Anmeldedaten zu MOASession " + session.getSessionID() + + " angelegt, SAML Artifakt " + samlArtifact); + return samlArtifact; + + } + + /** + * Stores authentication data indexed by the assertion handle contained in + * the given saml artifact. + * + * @param samlArtifact + * SAML artifact + * @param authData + * authentication data + * @throws AuthenticationException + * when SAML artifact is invalid + */ + private static void storeAuthenticationData(String samlArtifact, + AuthenticationData authData) throws AuthenticationException { + + try { + SAMLArtifactParser parser = new SAMLArtifactParser(samlArtifact); + // check type code 0x0001 + byte[] typeCode = parser.parseTypeCode(); + if (typeCode[0] != 0 || typeCode[1] != 1) + throw new AuthenticationException("auth.06", + new Object[] { samlArtifact }); + String assertionHandle = parser.parseAssertionHandle(); + synchronized (authenticationDataStore) { + Logger.debug("Assertion stored for SAML Artifact: " + + samlArtifact); + authenticationDataStore.put(assertionHandle, authData); + } + } catch (AuthenticationException ex) { + throw ex; + } catch (Throwable ex) { + throw new AuthenticationException("auth.06", + new Object[] { samlArtifact }); + } + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java new file mode 100644 index 000000000..601425a9c --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1Protocol.java @@ -0,0 +1,78 @@ +package at.gv.egovernment.moa.id.protocols.saml1; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; + +import at.gv.egovernment.moa.id.MOAIDException; +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.WrongParametersException; +import at.gv.egovernment.moa.id.moduls.IModulInfo; +import at.gv.egovernment.moa.id.moduls.ITargetConfiguration; +import at.gv.egovernment.moa.id.moduls.ServletInfo; +import at.gv.egovernment.moa.id.moduls.ServletType; +import at.gv.egovernment.moa.id.moduls.TargetConfigurationImpl; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; + +public class SAML1Protocol implements IModulInfo, MOAIDAuthConstants { + + public static final String NAME = SAML1Protocol.class.getName(); + public static final String PATH = "id_saml1"; + + public static final String GETARTIFACT = "GetArtifact"; + + private static List servletList = new ArrayList(); + + static { + servletList.add(new ServletInfo(GetArtifactServlet.class, GETARTIFACT, + ServletType.AUTH)); + + instance = new SAML1Protocol(); + } + + private static SAML1Protocol instance = null; + + public static SAML1Protocol getInstance() { + if (instance == null) { + instance = new SAML1Protocol(); + } + return instance; + } + + public List getServlets() { + return servletList; + } + + + public String getName() { + return NAME; + } + + public String getPath() { + return PATH; + } + + public ITargetConfiguration preProcess(HttpServletRequest request, + HttpServletResponse response) throws MOAIDException { + TargetConfigurationImpl config = new TargetConfigurationImpl(); + String oaURL = (String) request.getAttribute(PARAM_OA); + oaURL = StringEscapeUtils.escapeHtml(oaURL); + if (!ParamValidatorUtils.isValidOA(oaURL)) + throw new WrongParametersException("StartAuthentication", PARAM_OA, + "auth.12"); + config.setOAURL(oaURL); + request.getSession().setAttribute(PARAM_OA, oaURL); + return config; + } + + public boolean generateErrorMessage(Throwable e, + HttpServletRequest request, HttpServletResponse response) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPSessionUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPSessionUtils.java new file mode 100644 index 000000000..a8eef06a7 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPSessionUtils.java @@ -0,0 +1,41 @@ +package at.gv.egovernment.moa.id.util; + +import javax.servlet.http.HttpSession; + +public class HTTPSessionUtils { + + public static boolean getHTTPSessionBoolean(HttpSession session, String name, boolean fallback) { + Object obj = session.getAttribute(name); + if(obj == null) { + return fallback; + } + + if(obj instanceof Boolean) { + Boolean b = (Boolean)obj; + if(b != null) { + return b.booleanValue(); + } + } + return fallback; + } + + public static void setHTTPSessionBoolean(HttpSession session, String name, boolean value) { + session.setAttribute(name, new Boolean(value)); + } + + public static String getHTTPSessionString(HttpSession session, String name, String fallback) { + Object obj = session.getAttribute(name); + if(obj == null) { + return fallback; + } + + if(obj instanceof String) { + return (String)obj; + } + return fallback; + } + + public static void setHTTPSessionString(HttpSession session, String name, String value) { + session.setAttribute(name, value); + } +} diff --git a/id/server/idserverlib/src/main/resources/resources/templates/loginForm.html b/id/server/idserverlib/src/main/resources/resources/templates/loginForm.html new file mode 100644 index 000000000..90deb3b04 --- /dev/null +++ b/id/server/idserverlib/src/main/resources/resources/templates/loginForm.html @@ -0,0 +1,55 @@ + + + + + +
+
+
+ + + + +
+
+ Login mit Karte +
+ +
+
+
+ Login mit Handy +
+ +
+
+
+
+ + + i +
+
+ + \ No newline at end of file -- cgit v1.2.3