1 16 package org.mortbay.jetty.servlet; 17 18 import java.io.IOException ; 19 import java.io.Serializable ; 20 import java.security.Principal ; 21 22 import javax.servlet.http.HttpServletRequest ; 23 import javax.servlet.http.HttpServletResponse ; 24 import javax.servlet.http.HttpSession ; 25 import javax.servlet.http.HttpSessionBindingEvent ; 26 import javax.servlet.http.HttpSessionBindingListener ; 27 28 import org.apache.commons.logging.Log; 29 import org.mortbay.log.LogFactory; 30 import org.mortbay.http.Authenticator; 31 import org.mortbay.http.HttpRequest; 32 import org.mortbay.http.HttpResponse; 33 import org.mortbay.http.SSORealm; 34 import org.mortbay.http.SecurityConstraint; 35 import org.mortbay.http.UserRealm; 36 import org.mortbay.util.Credential; 37 import org.mortbay.util.Password; 38 import org.mortbay.util.URI; 39 40 41 50 public class FormAuthenticator implements Authenticator 51 { 52 static Log log = LogFactory.getLog(FormAuthenticator.class); 53 54 55 public final static String __J_URI="org.mortbay.jetty.URI"; 56 public final static String __J_AUTHENTICATED="org.mortbay.jetty.Auth"; 57 public final static String __J_SECURITY_CHECK="j_security_check"; 58 public final static String __J_USERNAME="j_username"; 59 public final static String __J_PASSWORD="j_password"; 60 61 private String _formErrorPage; 62 private String _formErrorPath; 63 private String _formLoginPage; 64 private String _formLoginPath; 65 66 67 public String getAuthMethod() 68 { 69 return HttpServletRequest.FORM_AUTH; 70 } 71 72 73 public void setLoginPage(String path) 74 { 75 if (!path.startsWith("/")) 76 { 77 log.warn("form-login-page must start with /"); 78 path="/"+path; 79 } 80 _formLoginPage=path; 81 _formLoginPath=path; 82 if (_formLoginPath.indexOf('?')>0) 83 _formLoginPath=_formLoginPath.substring(0,_formLoginPath.indexOf('?')); 84 } 85 86 87 public String getLoginPage() 88 { 89 return _formLoginPage; 90 } 91 92 93 public void setErrorPage(String path) 94 { 95 if (path==null || path.trim().length()==0) 96 { 97 _formErrorPath=null; 98 _formErrorPage=null; 99 } 100 else 101 { 102 if (!path.startsWith("/")) 103 { 104 log.warn("form-error-page must start with /"); 105 path="/"+path; 106 } 107 _formErrorPage=path; 108 _formErrorPath=path; 109 110 if (_formErrorPath!=null && _formErrorPath.indexOf('?')>0) 111 _formErrorPath=_formErrorPath.substring(0,_formErrorPath.indexOf('?')); 112 } 113 } 114 115 116 public String getErrorPage() 117 { 118 return _formErrorPage; 119 } 120 121 122 126 public Principal authenticate(UserRealm realm, 127 String pathInContext, 128 HttpRequest httpRequest, 129 HttpResponse httpResponse) 130 throws IOException 131 { 132 HttpServletRequest request =(ServletHttpRequest)httpRequest.getWrapper(); 133 HttpServletResponse response = httpResponse==null?null:(HttpServletResponse ) httpResponse.getWrapper(); 134 135 String uri = pathInContext; 137 138 HttpSession session=request.getSession(response!=null); 140 if (session==null) 141 return null; 142 143 if ( uri.substring(uri.lastIndexOf("/")+1).startsWith(__J_SECURITY_CHECK) ) 145 { 146 FormCredential form_cred=new FormCredential(); 148 form_cred.authenticate(realm, 149 request.getParameter(__J_USERNAME), 150 request.getParameter(__J_PASSWORD), 151 httpRequest); 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) 158 nuri="/"; 159 } 160 161 if (form_cred._userPrincipal!=null) 162 { 163 if(log.isDebugEnabled())log.debug("Form authentication OK for "+form_cred._jUserName); 165 session.removeAttribute(__J_URI); httpRequest.setAuthType(SecurityConstraint.__FORM_AUTH); 167 httpRequest.setAuthUser(form_cred._jUserName); 168 httpRequest.setUserPrincipal(form_cred._userPrincipal); 169 session.setAttribute(__J_AUTHENTICATED,form_cred); 170 171 if (realm instanceof SSORealm) 173 { 174 ((SSORealm)realm).setSingleSignOn(httpRequest, 175 httpResponse, 176 form_cred._userPrincipal, 177 new Password(form_cred._jPassword)); 178 } 179 180 if (response!=null) 182 { 183 response.setContentLength(0); 184 response.sendRedirect(response.encodeRedirectURL(nuri)); 185 } 186 } 187 else if (response!=null) 188 { 189 if(log.isDebugEnabled())log.debug("Form authentication FAILED for "+form_cred._jUserName); 190 if (_formErrorPage!=null) 191 { 192 response.setContentLength(0); 193 response.sendRedirect(response.encodeRedirectURL 194 (URI.addPaths(request.getContextPath(), 195 _formErrorPage))); 196 } 197 else 198 { 199 response.sendError(HttpResponse.__403_Forbidden); 200 } 201 } 202 203 return null; 205 } 206 207 FormCredential form_cred = (FormCredential) session.getAttribute(__J_AUTHENTICATED); 209 210 if (form_cred != null) 211 { 212 if (form_cred._userPrincipal==null) 214 { 215 form_cred.authenticate(realm, httpRequest); 217 218 if (form_cred._userPrincipal!=null && realm instanceof SSORealm) 220 { 221 ((SSORealm)realm).setSingleSignOn(httpRequest, 222 httpResponse, 223 form_cred._userPrincipal, 224 new Password(form_cred._jPassword)); 225 } 226 } 227 else if (!realm.reauthenticate(form_cred._userPrincipal)) 228 form_cred._userPrincipal=null; 230 231 if (form_cred._userPrincipal!=null) 233 { 234 if(log.isDebugEnabled())log.debug("FORM Authenticated for "+form_cred._userPrincipal.getName()); 235 httpRequest.setAuthType(SecurityConstraint.__FORM_AUTH); 236 httpRequest.setAuthUser(form_cred._userPrincipal.getName()); 237 httpRequest.setUserPrincipal(form_cred._userPrincipal); 238 return form_cred._userPrincipal; 239 } 240 else 241 session.setAttribute(__J_AUTHENTICATED,null); 242 } 243 else if (realm instanceof SSORealm) 244 { 245 Credential cred = ((SSORealm)realm).getSingleSignOn(httpRequest,httpResponse); 247 248 if (httpRequest.hasUserPrincipal()) 249 { 250 form_cred=new FormCredential(); 251 form_cred._userPrincipal=request.getUserPrincipal(); 252 form_cred._jUserName=form_cred._userPrincipal.getName(); 253 if (cred!=null) 254 form_cred._jPassword=cred.toString(); 255 if(log.isDebugEnabled())log.debug("SSO for "+form_cred._userPrincipal); 256 257 httpRequest.setAuthType(SecurityConstraint.__FORM_AUTH); 258 session.setAttribute(__J_AUTHENTICATED,form_cred); 259 return form_cred._userPrincipal; 260 } 261 } 262 263 if (isLoginOrErrorPage(pathInContext)) 265 return SecurityConstraint.__NOBODY; 266 267 if (response!=null) 269 { 270 if (httpRequest.getQuery()!=null) 271 uri+="?"+httpRequest.getQuery(); 272 session.setAttribute(__J_URI, 273 request.getScheme() + 274 "://" + request.getServerName() + 275 ":" + request.getServerPort() + 276 URI.addPaths(request.getContextPath(),uri)); 277 response.setContentLength(0); 278 response.sendRedirect(response.encodeRedirectURL(URI.addPaths(request.getContextPath(), 279 _formLoginPage))); 280 } 281 282 return null; 283 } 284 285 public boolean isLoginOrErrorPage(String pathInContext) 286 { 287 return pathInContext!=null && 288 (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath)); 289 } 290 291 292 294 private static class FormCredential implements Serializable , HttpSessionBindingListener 295 { 296 String _jUserName; 297 String _jPassword; 298 transient Principal _userPrincipal; 299 transient UserRealm _realm; 300 301 void authenticate(UserRealm realm,String user,String password,HttpRequest request) 302 { 303 _jUserName=user; 304 _jPassword=password; 305 _userPrincipal = realm.authenticate(user, password, request); 306 if (_userPrincipal!=null) 307 _realm=realm; 308 } 309 310 void authenticate(UserRealm realm,HttpRequest request) 311 { 312 _userPrincipal = realm.authenticate(_jUserName, _jPassword, request); 313 if (_userPrincipal!=null) 314 _realm=realm; 315 } 316 317 318 public void valueBound(HttpSessionBindingEvent event) {} 319 320 public void valueUnbound(HttpSessionBindingEvent event) 321 { 322 if(log.isDebugEnabled())log.debug("Logout "+_jUserName); 323 324 if(_realm instanceof SSORealm) 325 ((SSORealm)_realm).clearSingleSignOn(_jUserName); 326 327 if(_realm!=null && _userPrincipal!=null) 328 _realm.logout(_userPrincipal); 329 } 330 331 public int hashCode() 332 { 333 return _jUserName.hashCode()+_jPassword.hashCode(); 334 } 335 336 public boolean equals(Object o) 337 { 338 if (!(o instanceof FormCredential)) 339 return false; 340 FormCredential fc = (FormCredential)o; 341 return 342 _jUserName.equals(fc._jUserName) && 343 _jPassword.equals(fc._jPassword); 344 } 345 346 public String toString() 347 { 348 return "Cred["+_jUserName+"]"; 349 } 350 351 } 352 } 353 | Popular Tags |