comparison gwt-client/src/main/java/org/dive4elements/river/client/server/SamlServlet.java @ 5950:38d161edba77

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.
author Bernhard Herzog <bh@intevation.de>
date Wed, 08 May 2013 17:56:14 +0200
parents
children 24dc13ac8e6c
comparison
equal deleted inserted replaced
5949:0a0b4bfdf372 5950:38d161edba77
1 /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
2 * Software engineering by Intevation GmbH
3 *
4 * This file is Free Software under the GNU AGPL (>=v3)
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the
6 * documentation coming with Dive4Elements River for details.
7 */
8
9 package org.dive4elements.river.client.server;
10
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.io.StringBufferInputStream;
14
15 import javax.servlet.ServletException;
16 import javax.servlet.ServletContext;
17 import javax.servlet.http.HttpServlet;
18 import javax.servlet.http.HttpServletRequest;
19 import javax.servlet.http.HttpServletResponse;
20 import javax.servlet.http.HttpSession;
21
22 import org.apache.commons.codec.binary.Base64InputStream;
23
24 import org.apache.log4j.Logger;
25
26 import org.dive4elements.river.client.server.auth.AuthenticationException;
27 import org.dive4elements.river.client.server.auth.User;
28 import org.dive4elements.river.client.server.auth.UserClient;
29 import org.dive4elements.river.client.server.auth.saml.TicketValidator;
30 import org.dive4elements.river.client.server.auth.saml.Assertion;
31 import org.dive4elements.river.client.server.features.Features;
32
33
34 public class SamlServlet extends HttpServlet {
35
36 private static Logger logger = Logger.getLogger(SamlServlet.class);
37
38 private static final String FLYS_PAGE = "FLYS.html";
39 private static final String LOGIN_PAGE = "login.jsp";
40
41 private void redirectFailure(HttpServletResponse resp, String path)
42 throws IOException {
43 resp.sendRedirect(path + "/" + LOGIN_PAGE);
44 }
45
46 private void redirectFailure(HttpServletResponse resp, String path,
47 Exception e) throws IOException {
48 this.redirectFailure(resp, path, e.getMessage());
49 }
50
51 private void redirectFailure(HttpServletResponse resp, String path,
52 String message) throws IOException {
53 resp.sendRedirect(path + "/" + LOGIN_PAGE + "?error=" + message);
54 }
55
56 private void redirectSuccess(HttpServletResponse resp, String path,
57 String uri) throws IOException {
58 if (uri == null) {
59 String redirecturl = getServletContext().getInitParameter("redirect-url");
60 if (redirecturl == null) {
61 redirecturl = FLYS_PAGE;
62 }
63 uri = "/" + redirecturl;
64 }
65 resp.sendRedirect(uri);
66 }
67
68 @Override
69 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
70 throws ServletException, IOException {
71 logger.debug("Processing get request");
72 this.redirectFailure(resp, req.getContextPath());
73 }
74
75 @Override
76 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
77 throws ServletException, IOException
78 {
79 String encoding = req.getCharacterEncoding();
80 String samlTicketXML = req.getParameter("samlTicket");
81
82 logger.debug("Processing post request");
83
84 if (samlTicketXML == null) {
85 logger.debug("No saml ticket provided");
86 this.redirectFailure(resp, req.getContextPath());
87 return;
88 }
89
90 try {
91 User user = this.auth(samlTicketXML);
92 if (user == null) {
93 logger.debug("Authentication not successful");
94 this.redirectFailure(resp, req.getContextPath());
95 return;
96 }
97
98 String url = getServletContext().getInitParameter("server-url");
99 UserClient client = new UserClient(url);
100 if (!client.userExists(user)) {
101 logger.debug("Creating db user");
102 if (!client.createUser(user)) {
103 this.redirectFailure(resp, req.getContextPath(),
104 "Could not create new user");
105 return;
106 }
107 }
108
109 HttpSession session = req.getSession();
110 session.setAttribute("user", user);
111
112 String uri = (String)session.getAttribute("requesturi");
113
114 this.redirectSuccess(resp, req.getContextPath(), uri);
115 }
116 catch(AuthenticationException e) {
117 logger.error(e, e);
118 this.redirectFailure(resp, req.getContextPath(), e);
119 }
120 }
121
122 private User auth(String samlTicketXML)
123 throws AuthenticationException, IOException
124 {
125 ServletContext sc = this.getServletContext();
126
127 Assertion assertion = null;
128 try {
129 String keyfile =
130 (String)sc.getInitParameter("saml-trusted-public-key");
131 TicketValidator validator =
132 new TicketValidator(sc.getRealPath(keyfile));
133
134 InputStream in = new StringBufferInputStream(samlTicketXML);
135 assertion = validator.checkTicket(new Base64InputStream(in));
136 }
137 catch (Exception e) {
138 logger.error(e.getLocalizedMessage(), e);
139 }
140 if (assertion == null) {
141 throw new AuthenticationException("Login failed.");
142 }
143
144 Features features = (Features)sc.getAttribute(Features.CONTEXT_ATTRIBUTE);
145 return new org.dive4elements.river.client.server.auth.saml.User(
146 assertion, features.getFeatures(assertion.getRoles()), null);
147 }
148 }

http://dive4elements.wald.intevation.org