1 17 package org.apache.geronimo.tomcat.realm; 18 19 import org.apache.catalina.Context; 20 import org.apache.catalina.LifecycleException; 21 import org.apache.catalina.connector.Request; 22 import org.apache.catalina.connector.Response; 23 import org.apache.catalina.deploy.LoginConfig; 24 import org.apache.catalina.deploy.SecurityConstraint; 25 import org.apache.catalina.realm.JAASRealm; 26 import org.apache.commons.logging.Log; 27 import org.apache.commons.logging.LogFactory; 28 import org.apache.geronimo.security.ContextManager; 29 import org.apache.geronimo.security.jacc.PolicyContextHandlerContainerSubject; 30 import org.apache.geronimo.security.realm.providers.CertificateChainCallbackHandler; 31 import org.apache.geronimo.security.realm.providers.PasswordCallbackHandler; 32 import org.apache.geronimo.tomcat.JAASTomcatPrincipal; 33 34 import javax.security.auth.Subject ; 35 import javax.security.auth.callback.CallbackHandler ; 36 import javax.security.auth.login.AccountExpiredException ; 37 import javax.security.auth.login.CredentialExpiredException ; 38 import javax.security.auth.login.FailedLoginException ; 39 import javax.security.auth.login.LoginContext ; 40 import javax.security.auth.login.LoginException ; 41 import javax.security.jacc.PolicyContext ; 42 import javax.security.jacc.PolicyContextException ; 43 import javax.security.jacc.WebResourcePermission ; 44 import javax.security.jacc.WebRoleRefPermission ; 45 import javax.security.jacc.WebUserDataPermission ; 46 47 import java.io.IOException ; 48 import java.security.AccessControlContext ; 49 import java.security.AccessControlException ; 50 import java.security.Principal ; 51 import java.security.cert.X509Certificate ; 52 53 54 public class TomcatGeronimoRealm extends JAASRealm { 55 56 private static final Log log = LogFactory.getLog(TomcatGeronimoRealm.class); 57 58 private static ThreadLocal currentRequestWrapperName = new ThreadLocal (); 59 60 63 protected static final String info = "org.apache.geronimo.tomcat.TomcatGeronimoRealm/1.0"; 64 65 68 protected static final String name = "TomcatGeronimoRealm"; 69 70 public TomcatGeronimoRealm() { 71 72 } 73 74 public static String setRequestWrapperName(String requestWrapperName) { 75 String old = (String ) currentRequestWrapperName.get(); 76 currentRequestWrapperName.set(requestWrapperName); 77 return old; 78 } 79 80 91 public boolean hasUserDataPermission(Request request, 92 Response response, 93 SecurityConstraint[] constraints) 94 throws IOException { 95 96 Subject subject = null; 98 try { 99 100 subject = (Subject) PolicyContext.getContext(PolicyContextHandlerContainerSubject.HANDLER_KEY); 104 105 } catch (PolicyContextException e) { 106 log.error(e); 107 } 108 109 if (subject == null) 111 return super.hasUserDataPermission(request, response, constraints); 112 113 ContextManager.setCallers(subject, subject); 114 115 try { 116 117 AccessControlContext acc = ContextManager.getCurrentContext(); 118 119 122 WebUserDataPermission wudp = new WebUserDataPermission (request); 123 acc.checkPermission(wudp); 124 125 } catch (AccessControlException ace) { 126 response.sendError(Response.SC_FORBIDDEN); 127 return false; 128 } 129 130 return true; 131 } 132 133 144 public boolean hasResourcePermission(Request request, 145 Response response, 146 SecurityConstraint[] constraints, 147 Context context) 148 throws IOException { 149 150 LoginConfig config = context.getLoginConfig(); 153 if ((config != null) && 154 (org.apache.catalina.realm.Constants.FORM_METHOD.equals(config.getAuthMethod()))) { 155 String requestURI = request.getDecodedRequestURI(); 156 String loginPage = context.getPath() + config.getLoginPage(); 157 if (loginPage.equals(requestURI)) { 158 if (log.isDebugEnabled()) 159 log.debug(" Allow access to login page " + loginPage); 160 return (true); 161 } 162 String errorPage = context.getPath() + config.getErrorPage(); 163 if (errorPage.equals(requestURI)) { 164 if (log.isDebugEnabled()) 165 log.debug(" Allow access to error page " + errorPage); 166 return (true); 167 } 168 if (requestURI.endsWith(org.apache.catalina.realm.Constants.FORM_ACTION)) { 169 if (log.isDebugEnabled()) 170 log.debug(" Allow access to username/password submission"); 171 return (true); 172 } 173 } 174 175 currentRequestWrapperName.set(request.getWrapper().getName()); 177 178 Principal principal = request.getUserPrincipal(); 180 181 if (principal == null) { 183 return request.isSecure(); 184 185 } else { 186 Subject currentCaller = ((JAASTomcatPrincipal) principal).getSubject(); 187 ContextManager.setCallers(currentCaller, currentCaller); 188 } 189 190 try { 191 192 AccessControlContext acc = ContextManager.getCurrentContext(); 193 194 195 198 acc.checkPermission(new WebResourcePermission (request)); 199 200 } catch (AccessControlException ace) { 201 response.sendError(Response.SC_FORBIDDEN); 202 return false; 203 } 204 205 return true; 206 207 } 208 209 217 public boolean hasRole(Principal principal, String role) { 218 219 if ((principal == null) || (role == null) || !(principal instanceof JAASTomcatPrincipal)) { 220 return false; 221 } 222 223 String name = (String )currentRequestWrapperName.get(); 224 225 228 if (name == null || name.equals("jsp")) { 229 name = ""; 230 } 231 232 Subject currentCaller = ((JAASTomcatPrincipal) principal).getSubject(); 234 ContextManager.setCallers(currentCaller, currentCaller); 235 236 AccessControlContext acc = ContextManager.getCurrentContext(); 237 238 try { 239 242 acc.checkPermission(new WebRoleRefPermission (name, role)); 243 } catch (AccessControlException e) { 244 return false; 245 } 246 247 return true; 248 } 249 250 264 public Principal authenticate(String username, String credentials) { 265 266 char[] cred = credentials == null? null: credentials.toCharArray(); 267 CallbackHandler callbackHandler = new PasswordCallbackHandler(username, cred); 268 return authenticate(callbackHandler, username); 269 } 270 271 public Principal authenticate(X509Certificate [] certs) { 272 if (certs == null || certs.length == 0) { 273 return null; 274 } 275 CallbackHandler callbackHandler = new CertificateChainCallbackHandler(certs); 276 String principalName = certs[0].getSubjectX500Principal().getName(); 277 return authenticate(callbackHandler, principalName); 278 } 279 280 public Principal authenticate(CallbackHandler callbackHandler, String principalName) { 281 282 try { 284 285 if ( (principalName!=null) && (!principalName.equals("")) ) { 286 LoginContext loginContext = null; 287 if (appName == null) 288 appName = "Tomcat"; 289 290 if (log.isDebugEnabled()) 291 log.debug(sm.getString("jaasRealm.beginLogin", principalName, appName)); 292 293 ClassLoader ocl = null; 295 296 if (isUseContextClassLoader()) { 297 ocl = Thread.currentThread().getContextClassLoader(); 298 Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); 299 } 300 301 try { 302 loginContext = new LoginContext (appName, callbackHandler); 303 } catch (Throwable e) { 304 log.error(sm.getString("jaasRealm.unexpectedError"), e); 305 return (null); 306 } finally { 307 if (isUseContextClassLoader()) { 308 Thread.currentThread().setContextClassLoader(ocl); 309 } 310 } 311 312 if (log.isDebugEnabled()) 313 log.debug("Login context created " + principalName); 314 315 Subject subject; 317 try { 318 loginContext.login(); 319 Subject tempSubject = loginContext.getSubject(); 320 if (tempSubject == null) { 321 if (log.isDebugEnabled()) 322 log.debug(sm.getString("jaasRealm.failedLogin", principalName)); 323 return (null); 324 } 325 326 subject = ContextManager.getServerSideSubject(tempSubject); 327 if (subject == null) { 328 if (log.isDebugEnabled()) 329 log.debug(sm.getString("jaasRealm.failedLogin", principalName)); 330 return (null); 331 } 332 333 ContextManager.setCallers(subject, subject); 334 335 } catch (AccountExpiredException e) { 336 if (log.isDebugEnabled()) 337 log.debug(sm.getString("jaasRealm.accountExpired", principalName)); 338 return (null); 339 } catch (CredentialExpiredException e) { 340 if (log.isDebugEnabled()) 341 log.debug(sm.getString("jaasRealm.credentialExpired", principalName)); 342 return (null); 343 } catch (FailedLoginException e) { 344 if (log.isDebugEnabled()) 345 log.debug(sm.getString("jaasRealm.failedLogin", principalName)); 346 return (null); 347 } catch (LoginException e) { 348 log.warn(sm.getString("jaasRealm.loginException", principalName), e); 349 return (null); 350 } catch (Throwable e) { 351 log.error(sm.getString("jaasRealm.unexpectedError"), e); 352 return (null); 353 } 354 355 if (log.isDebugEnabled()) 356 log.debug(sm.getString("jaasRealm.loginContextCreated", principalName)); 357 358 368 JAASTomcatPrincipal jaasPrincipal = new JAASTomcatPrincipal(principalName); 369 jaasPrincipal.setSubject(subject); 370 371 return (jaasPrincipal); 372 } 373 else { 374 if (log.isDebugEnabled()) 375 log.debug("Login Failed - null userID"); 376 return null; 377 } 378 379 } catch (Throwable t) { 380 log.error("error ", t); 381 return null; 382 } 383 } 384 391 public void start() throws LifecycleException { 392 393 super.start(); 395 396 } 397 398 404 public void stop() throws LifecycleException { 405 406 super.stop(); 408 409 } 410 } 411 | Popular Tags |