Implemented AuthenticatingHttpServlet which automatically authenticates the requestin...
[guacamole.git] / src / main / java / net / sourceforge / guacamole / net / basic / AuthenticatingHttpServlet.java
1
2 package net.sourceforge.guacamole.net.basic;
3
4 import java.io.IOException;
5 import java.util.Map;
6 import javax.servlet.ServletException;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10 import javax.servlet.http.HttpSession;
11 import net.sourceforge.guacamole.GuacamoleException;
12 import net.sourceforge.guacamole.net.auth.AuthenticationProvider;
13 import net.sourceforge.guacamole.net.auth.Credentials;
14 import net.sourceforge.guacamole.net.basic.properties.BasicGuacamoleProperties;
15 import net.sourceforge.guacamole.properties.GuacamoleProperties;
16 import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 /**
21  * Abstract servlet which provides an authenticatedService() function that
22  * is only called if the HTTP request is authenticated, or the current
23  * HTTP session has already been authenticated.
24  * 
25  * Authorized configurations are retrieved using the authentication provider
26  * defined in guacamole.properties. The authentication provider has access
27  * to the request and session, in addition to any submitted username and
28  * password, in order to authenticate the user.
29  * 
30  * All authorized configurations will be stored in the current HttpSession.
31  * 
32  * Success and failure are logged.
33  * 
34  * @author Michael Jumper
35  */
36 public abstract class AuthenticatingHttpServlet extends HttpServlet {
37
38     private Logger logger = LoggerFactory.getLogger(AuthenticatingHttpServlet.class);
39     
40     private AuthenticationProvider authProvider;
41
42     @Override
43     public void init() throws ServletException {
44
45         // Get auth provider instance
46         try {
47             authProvider = GuacamoleProperties.getRequiredProperty(BasicGuacamoleProperties.AUTH_PROVIDER);
48         }
49         catch (GuacamoleException e) {
50             logger.error("Error getting authentication provider from properties.", e);
51             throw new ServletException(e);
52         }
53
54     }
55
56     @Override
57     protected void service(HttpServletRequest request, HttpServletResponse response)
58     throws IOException, ServletException {
59
60         HttpSession httpSession = request.getSession(true);
61
62         // Try to get configs from session
63         Map<String, GuacamoleConfiguration> configs =
64                 (Map<String, GuacamoleConfiguration>) httpSession.getAttribute("GUAC_CONFIGS");
65
66         // If no configs, try to authenticate the user to get the configs using
67         // this request.
68         if (configs == null) {
69
70             // Retrieve username and password from parms
71             String username = request.getParameter("username");
72             String password = request.getParameter("password");
73
74             // Build credentials object
75             Credentials credentials = new Credentials ();
76             credentials.setSession(httpSession);
77             credentials.setRequest(request);
78             credentials.setUsername(username);
79             credentials.setPassword(password);
80             
81             // Get authorized configs
82             try {
83                 configs = authProvider.getAuthorizedConfigurations(credentials);
84             }
85             catch (GuacamoleException e) {
86                 logger.error("Error retrieving configuration(s) for user {}.", username);
87                 response.sendError(HttpServletResponse.SC_FORBIDDEN);
88                 return;
89             }
90             
91             if (configs == null) {
92                 logger.warn("Authentication attempt from {} for user \"{}\".",
93                         request.getRemoteAddr(), username);
94                 response.sendError(HttpServletResponse.SC_FORBIDDEN);
95                 return;
96             }
97
98             logger.info("User \"{}\" successfully authenticated from {}.",
99                     username, request.getRemoteAddr());
100
101             // Associate configs with session
102             httpSession.setAttribute("GUAC_CONFIGS", configs);
103
104         }
105
106         // Allow servlet to run now that authentication has been validated
107         authenticatedService(configs, request, response);
108
109     }
110
111     protected abstract void authenticatedService(
112             Map<String, GuacamoleConfiguration> configs,
113             HttpServletRequest request, HttpServletResponse response)
114             throws ServletException, IOException;
115
116 }