[Dive4elements-commits] [PATCH 18 of 21] Add SamlServlet to implement actual login via SAML Ticket
Wald Commits
scm-commit at wald.intevation.org
Wed May 8 18:08:28 CEST 2013
# HG changeset patch
# User Bernhard Herzog <bh at intevation.de>
# Date 1368028574 -7200
# Node ID 38d161edba77fe1e8c4c41821dc2efc054ce4fc5
# Parent 0a0b4bfdf3721d036487989c008440a924171abf
Add SamlServlet to implement actual login via SAML Ticket.
This is the main part of single-sign-on for flys from issue1265.
SamlServlet is an adapted copy of LoginServlet. The code shared by both
classes will be extracted into a base class later.
diff -r 0a0b4bfdf372 -r 38d161edba77 gwt-client/src/main/java/org/dive4elements/river/client/server/SamlServlet.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/SamlServlet.java Wed May 08 17:56:14 2013 +0200
@@ -0,0 +1,148 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.codec.binary.Base64InputStream;
+
+import org.apache.log4j.Logger;
+
+import org.dive4elements.river.client.server.auth.AuthenticationException;
+import org.dive4elements.river.client.server.auth.User;
+import org.dive4elements.river.client.server.auth.UserClient;
+import org.dive4elements.river.client.server.auth.saml.TicketValidator;
+import org.dive4elements.river.client.server.auth.saml.Assertion;
+import org.dive4elements.river.client.server.features.Features;
+
+
+public class SamlServlet extends HttpServlet {
+
+ private static Logger logger = Logger.getLogger(SamlServlet.class);
+
+ private static final String FLYS_PAGE = "FLYS.html";
+ private static final String LOGIN_PAGE = "login.jsp";
+
+ private void redirectFailure(HttpServletResponse resp, String path)
+ throws IOException {
+ resp.sendRedirect(path + "/" + LOGIN_PAGE);
+ }
+
+ private void redirectFailure(HttpServletResponse resp, String path,
+ Exception e) throws IOException {
+ this.redirectFailure(resp, path, e.getMessage());
+ }
+
+ private void redirectFailure(HttpServletResponse resp, String path,
+ String message) throws IOException {
+ resp.sendRedirect(path + "/" + LOGIN_PAGE + "?error=" + message);
+ }
+
+ private void redirectSuccess(HttpServletResponse resp, String path,
+ String uri) throws IOException {
+ if (uri == null) {
+ String redirecturl = getServletContext().getInitParameter("redirect-url");
+ if (redirecturl == null) {
+ redirecturl = FLYS_PAGE;
+ }
+ uri = "/" + redirecturl;
+ }
+ resp.sendRedirect(uri);
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ logger.debug("Processing get request");
+ this.redirectFailure(resp, req.getContextPath());
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ String encoding = req.getCharacterEncoding();
+ String samlTicketXML = req.getParameter("samlTicket");
+
+ logger.debug("Processing post request");
+
+ if (samlTicketXML == null) {
+ logger.debug("No saml ticket provided");
+ this.redirectFailure(resp, req.getContextPath());
+ return;
+ }
+
+ try {
+ User user = this.auth(samlTicketXML);
+ if (user == null) {
+ logger.debug("Authentication not successful");
+ this.redirectFailure(resp, req.getContextPath());
+ return;
+ }
+
+ String url = getServletContext().getInitParameter("server-url");
+ UserClient client = new UserClient(url);
+ if (!client.userExists(user)) {
+ logger.debug("Creating db user");
+ if (!client.createUser(user)) {
+ this.redirectFailure(resp, req.getContextPath(),
+ "Could not create new user");
+ return;
+ }
+ }
+
+ HttpSession session = req.getSession();
+ session.setAttribute("user", user);
+
+ String uri = (String)session.getAttribute("requesturi");
+
+ this.redirectSuccess(resp, req.getContextPath(), uri);
+ }
+ catch(AuthenticationException e) {
+ logger.error(e, e);
+ this.redirectFailure(resp, req.getContextPath(), e);
+ }
+ }
+
+ private User auth(String samlTicketXML)
+ throws AuthenticationException, IOException
+ {
+ ServletContext sc = this.getServletContext();
+
+ Assertion assertion = null;
+ try {
+ String keyfile =
+ (String)sc.getInitParameter("saml-trusted-public-key");
+ TicketValidator validator =
+ new TicketValidator(sc.getRealPath(keyfile));
+
+ InputStream in = new StringBufferInputStream(samlTicketXML);
+ assertion = validator.checkTicket(new Base64InputStream(in));
+ }
+ catch (Exception e) {
+ logger.error(e.getLocalizedMessage(), e);
+ }
+ if (assertion == null) {
+ throw new AuthenticationException("Login failed.");
+ }
+
+ Features features = (Features)sc.getAttribute(Features.CONTEXT_ATTRIBUTE);
+ return new org.dive4elements.river.client.server.auth.saml.User(
+ assertion, features.getFeatures(assertion.getRoles()), null);
+ }
+}
More information about the Dive4elements-commits
mailing list