Mercurial > dive4elements > river
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 } |