1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.security.authentication;
15
16 import java.io.IOException;
17
18 import javax.servlet.RequestDispatcher;
19 import javax.servlet.ServletException;
20 import javax.servlet.ServletRequest;
21 import javax.servlet.ServletResponse;
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24 import javax.servlet.http.HttpSession;
25
26 import org.eclipse.jetty.http.HttpHeaders;
27 import org.eclipse.jetty.http.security.Constraint;
28 import org.eclipse.jetty.security.Authentication;
29 import org.eclipse.jetty.security.DefaultAuthentication;
30 import org.eclipse.jetty.security.ServerAuthException;
31 import org.eclipse.jetty.server.UserIdentity;
32 import org.eclipse.jetty.util.StringUtil;
33 import org.eclipse.jetty.util.URIUtil;
34 import org.eclipse.jetty.util.log.Log;
35
36
37
38
39 public class FormAuthenticator extends LoginAuthenticator
40 {
41 public final static String __FORM_LOGIN_PAGE="org.eclipse.jetty.security.form_login_page";
42 public final static String __FORM_ERROR_PAGE="org.eclipse.jetty.security.form_error_page";
43 public final static String __FORM_DISPATCH="org.eclipse.jetty.security.dispatch";
44 public final static String __J_URI = "org.eclipse.jetty.util.URI";
45 public final static String __J_AUTHENTICATED = "org.eclipse.jetty.server.Auth";
46 public final static String __J_SECURITY_CHECK = "/j_security_check";
47 public final static String __J_USERNAME = "j_username";
48 public final static String __J_PASSWORD = "j_password";
49 private String _formErrorPage;
50 private String _formErrorPath;
51 private String _formLoginPage;
52 private String _formLoginPath;
53 private boolean _dispatch;
54
55 public FormAuthenticator()
56 {
57 }
58
59
60 public FormAuthenticator(String login,String error)
61 {
62 if (login!=null)
63 setLoginPage(login);
64 if (error!=null)
65 setErrorPage(error);
66 }
67
68
69
70
71
72 @Override
73 public void setConfiguration(Configuration configuration)
74 {
75 super.setConfiguration(configuration);
76 String login=configuration.getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE);
77 if (login!=null)
78 setLoginPage(login);
79 String error=configuration.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE);
80 if (error!=null)
81 setErrorPage(error);
82 String dispatch=configuration.getInitParameter(FormAuthenticator.__FORM_DISPATCH);
83 _dispatch=dispatch!=null && Boolean.getBoolean(dispatch);
84 }
85
86 public String getAuthMethod()
87 {
88 return Constraint.__FORM_AUTH;
89 }
90
91 private void setLoginPage(String path)
92 {
93 if (!path.startsWith("/"))
94 {
95 Log.warn("form-login-page must start with /");
96 path = "/" + path;
97 }
98 _formLoginPage = path;
99 _formLoginPath = path;
100 if (_formLoginPath.indexOf('?') > 0)
101 _formLoginPath = _formLoginPath.substring(0, _formLoginPath.indexOf('?'));
102 }
103
104
105 private void setErrorPage(String path)
106 {
107 if (path == null || path.trim().length() == 0)
108 {
109 _formErrorPath = null;
110 _formErrorPage = null;
111 }
112 else
113 {
114 if (!path.startsWith("/"))
115 {
116 Log.warn("form-error-page must start with /");
117 path = "/" + path;
118 }
119 _formErrorPage = path;
120 _formErrorPath = path;
121
122 if (_formErrorPath.indexOf('?') > 0)
123 _formErrorPath = _formErrorPath.substring(0, _formErrorPath.indexOf('?'));
124 }
125 }
126
127 public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
128 {
129 HttpServletRequest request = (HttpServletRequest)req;
130 HttpServletResponse response = (HttpServletResponse)res;
131 HttpSession session = request.getSession(mandatory);
132 String uri = request.getPathInfo();
133
134 if (session == null || isLoginOrErrorPage(uri))
135 {
136 return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS;
137 }
138
139
140 try
141 {
142
143
144 if (uri.endsWith(__J_SECURITY_CHECK))
145 {
146 final String username = request.getParameter(__J_USERNAME);
147 final char[] password = request.getParameter(__J_PASSWORD).toCharArray();
148
149 UserIdentity user = _loginService.login(username,password);
150 if (user!=null)
151 {
152
153 String nuri = (String) session.getAttribute(__J_URI);
154 if (nuri == null || nuri.length() == 0)
155 {
156 nuri = request.getContextPath();
157 if (nuri.length() == 0) nuri = URIUtil.SLASH;
158 }
159
160 session.removeAttribute(__J_URI);
161 response.setContentLength(0);
162 response.sendRedirect(response.encodeRedirectURL(nuri));
163 return new DefaultAuthentication(Authentication.Status.SEND_SUCCESS,Constraint.__FORM_AUTH,user);
164 }
165
166
167 if (Log.isDebugEnabled()) Log.debug("Form authentication FAILED for " + StringUtil.printable(username));
168 if (_formErrorPage == null)
169 {
170 if (response != null)
171 response.sendError(HttpServletResponse.SC_FORBIDDEN);
172 }
173 else if (_dispatch)
174 {
175 RequestDispatcher dispatcher = request.getRequestDispatcher(_formErrorPage);
176 response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache");
177 response.setDateHeader(HttpHeaders.EXPIRES,1);
178 dispatcher.forward(request, response);
179 }
180 else
181 {
182 response.sendRedirect(URIUtil.addPaths(request.getContextPath(),_formErrorPage));
183 }
184
185
186
187 return DefaultAuthentication.SEND_FAILURE_RESULTS;
188 }
189
190
191
192 if (!mandatory)
193
194 return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS;
195
196
197 if (request.getQueryString() != null)
198 uri += "?" + request.getQueryString();
199
200 session.setAttribute(__J_URI, request.getScheme() + "://"
201 + request.getServerName()
202 + ":"
203 + request.getServerPort()
204 + URIUtil.addPaths(request.getContextPath(), uri));
205
206 if (_dispatch)
207 {
208 RequestDispatcher dispatcher = request.getRequestDispatcher(_formLoginPage);
209 response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache");
210 response.setDateHeader(HttpHeaders.EXPIRES,1);
211 dispatcher.forward(request, response);
212 }
213 else
214 {
215 response.sendRedirect(URIUtil.addPaths(request.getContextPath(),_formLoginPage));
216 }
217
218 return DefaultAuthentication.SEND_CONTINUE_RESULTS;
219 }
220 catch (IOException e)
221 {
222 throw new ServerAuthException(e);
223 }
224 catch (ServletException e)
225 {
226 throw new ServerAuthException(e);
227 }
228 }
229
230 public boolean isLoginOrErrorPage(String pathInContext)
231 {
232 return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath));
233 }
234
235 public Authentication.Status secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
236 {
237 return Authentication.Status.SUCCESS;
238 }
239 }