1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.security.jaspi.modules;
20
21 import java.io.IOException;
22 import java.util.Map;
23 import java.util.Set;
24
25 import javax.security.auth.Subject;
26 import javax.security.auth.callback.CallbackHandler;
27 import javax.security.auth.callback.UnsupportedCallbackException;
28 import javax.security.auth.message.AuthException;
29 import javax.security.auth.message.AuthStatus;
30 import javax.security.auth.message.MessageInfo;
31 import javax.security.auth.message.MessagePolicy;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpServletResponse;
34 import javax.servlet.http.HttpSession;
35
36 import org.eclipse.jetty.security.authentication.DeferredAuthentication;
37 import org.eclipse.jetty.security.authentication.LoginCallbackImpl;
38 import org.eclipse.jetty.security.authentication.SessionAuthentication;
39 import org.eclipse.jetty.server.UserIdentity;
40 import org.eclipse.jetty.util.StringUtil;
41 import org.eclipse.jetty.util.URIUtil;
42 import org.eclipse.jetty.util.log.Log;
43 import org.eclipse.jetty.util.log.Logger;
44 import org.eclipse.jetty.util.security.Constraint;
45 import org.eclipse.jetty.util.security.Password;
46
47 @Deprecated
48 public class FormAuthModule extends BaseAuthModule
49 {
50 private static final Logger LOG = Log.getLogger(FormAuthModule.class);
51
52
53 public final static String __J_URI = "org.eclipse.jetty.util.URI";
54
55 public final static String __J_AUTHENTICATED = "org.eclipse.jetty.server.Auth";
56
57 public final static String __J_SECURITY_CHECK = "/j_security_check";
58
59 public final static String __J_USERNAME = "j_username";
60
61 public final static String __J_PASSWORD = "j_password";
62
63
64 public static final String LOGIN_PAGE_KEY = "org.eclipse.jetty.security.jaspi.modules.LoginPage";
65
66 public static final String ERROR_PAGE_KEY = "org.eclipse.jetty.security.jaspi.modules.ErrorPage";
67
68 public static final String SSO_SOURCE_KEY = "org.eclipse.jetty.security.jaspi.modules.SsoSource";
69
70 private String _formErrorPage;
71
72 private String _formErrorPath;
73
74 private String _formLoginPage;
75
76 private String _formLoginPath;
77
78
79 public FormAuthModule()
80 {
81 }
82
83 public FormAuthModule(CallbackHandler callbackHandler, String loginPage, String errorPage)
84 {
85 super(callbackHandler);
86 setLoginPage(loginPage);
87 setErrorPage(errorPage);
88 }
89
90
91 @Override
92 public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy,
93 CallbackHandler handler, Map options)
94 throws AuthException
95 {
96 super.initialize(requestPolicy, responsePolicy, handler, options);
97 setLoginPage((String) options.get(LOGIN_PAGE_KEY));
98 setErrorPage((String) options.get(ERROR_PAGE_KEY));
99 }
100
101 private void setLoginPage(String path)
102 {
103 if (!path.startsWith("/"))
104 {
105 LOG.warn("form-login-page must start with /");
106 path = "/" + path;
107 }
108 _formLoginPage = path;
109 _formLoginPath = path;
110 if (_formLoginPath.indexOf('?') > 0) _formLoginPath = _formLoginPath.substring(0, _formLoginPath.indexOf('?'));
111 }
112
113
114 private void setErrorPage(String path)
115 {
116 if (path == null || path.trim().length() == 0)
117 {
118 _formErrorPath = null;
119 _formErrorPage = null;
120 }
121 else
122 {
123 if (!path.startsWith("/"))
124 {
125 LOG.warn("form-error-page must start with /");
126 path = "/" + path;
127 }
128 _formErrorPage = path;
129 _formErrorPath = path;
130
131 if (_formErrorPath.indexOf('?') > 0) _formErrorPath = _formErrorPath.substring(0, _formErrorPath.indexOf('?'));
132 }
133 }
134
135 @Override
136 public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException
137 {
138
139 HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
140 HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage();
141 String uri = request.getRequestURI();
142 if (uri==null)
143 uri=URIUtil.SLASH;
144
145 boolean mandatory = isMandatory(messageInfo);
146 mandatory |= isJSecurityCheck(uri);
147 HttpSession session = request.getSession(mandatory);
148
149
150 if (!mandatory || isLoginOrErrorPage(URIUtil.addPaths(request.getServletPath(),request.getPathInfo())))
151 return AuthStatus.SUCCESS;
152
153 try
154 {
155
156 if (isJSecurityCheck(uri))
157 {
158 final String username = request.getParameter(__J_USERNAME);
159 final String password = request.getParameter(__J_PASSWORD);
160
161 boolean success = tryLogin(messageInfo, clientSubject, response, session, username, new Password(password));
162 if (success)
163 {
164
165 String nuri=null;
166 synchronized(session)
167 {
168 nuri = (String) session.getAttribute(__J_URI);
169 }
170
171 if (nuri == null || nuri.length() == 0)
172 {
173 nuri = request.getContextPath();
174 if (nuri.length() == 0)
175 nuri = URIUtil.SLASH;
176 }
177
178 response.setContentLength(0);
179 response.sendRedirect(response.encodeRedirectURL(nuri));
180 return AuthStatus.SEND_CONTINUE;
181 }
182
183 if (LOG.isDebugEnabled()) LOG.debug("Form authentication FAILED for " + StringUtil.printable(username));
184 if (_formErrorPage == null)
185 {
186 if (response != null) response.sendError(HttpServletResponse.SC_FORBIDDEN);
187 }
188 else
189 {
190 response.setContentLength(0);
191 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(), _formErrorPage)));
192 }
193
194
195 return AuthStatus.SEND_FAILURE;
196 }
197
198
199
200 SessionAuthentication sessionAuth = (SessionAuthentication)session.getAttribute(SessionAuthentication.__J_AUTHENTICATED);
201 if (sessionAuth != null)
202 {
203
204
205
206 if (sessionAuth.getUserIdentity().getSubject() == null)
207 return AuthStatus.SEND_FAILURE;
208
209 Set<Object> credentials = sessionAuth.getUserIdentity().getSubject().getPrivateCredentials();
210 if (credentials == null || credentials.isEmpty())
211 return AuthStatus.SEND_FAILURE;
212
213 clientSubject.getPrivateCredentials().addAll(credentials);
214 clientSubject.getPrivateCredentials().add(sessionAuth.getUserIdentity());
215
216 return AuthStatus.SUCCESS;
217 }
218
219
220
221 if (DeferredAuthentication.isDeferred(response))
222 return AuthStatus.SUCCESS;
223
224
225
226 StringBuffer buf = request.getRequestURL();
227 if (request.getQueryString() != null)
228 buf.append("?").append(request.getQueryString());
229
230 synchronized (session)
231 {
232 session.setAttribute(__J_URI, buf.toString());
233 }
234
235 response.setContentLength(0);
236 response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(), _formLoginPage)));
237 return AuthStatus.SEND_CONTINUE;
238 }
239 catch (IOException e)
240 {
241 throw new AuthException(e.getMessage());
242 }
243 catch (UnsupportedCallbackException e)
244 {
245 throw new AuthException(e.getMessage());
246 }
247
248 }
249
250
251 public boolean isJSecurityCheck(String uri)
252 {
253 int jsc = uri.indexOf(__J_SECURITY_CHECK);
254
255 if (jsc<0)
256 return false;
257 int e=jsc+__J_SECURITY_CHECK.length();
258 if (e==uri.length())
259 return true;
260 char c = uri.charAt(e);
261 return c==';'||c=='#'||c=='/'||c=='?';
262 }
263
264 private boolean tryLogin(MessageInfo messageInfo, Subject clientSubject,
265 HttpServletResponse response, HttpSession session,
266 String username, Password password)
267 throws AuthException, IOException, UnsupportedCallbackException
268 {
269 if (login(clientSubject, username, password, Constraint.__FORM_AUTH, messageInfo))
270 {
271 char[] pwdChars = password.toString().toCharArray();
272 Set<LoginCallbackImpl> loginCallbacks = clientSubject.getPrivateCredentials(LoginCallbackImpl.class);
273
274 if (!loginCallbacks.isEmpty())
275 {
276 LoginCallbackImpl loginCallback = loginCallbacks.iterator().next();
277 Set<UserIdentity> userIdentities = clientSubject.getPrivateCredentials(UserIdentity.class);
278 if (!userIdentities.isEmpty())
279 {
280 UserIdentity userIdentity = userIdentities.iterator().next();
281
282 SessionAuthentication sessionAuth = new SessionAuthentication(Constraint.__FORM_AUTH, userIdentity, password);
283 session.setAttribute(SessionAuthentication.__J_AUTHENTICATED, sessionAuth);
284 }
285 }
286
287 return true;
288 }
289 return false;
290 }
291
292 public boolean isLoginOrErrorPage(String pathInContext)
293 {
294 return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath));
295 }
296
297 }