1 22 package org.jboss.web.tomcat.security; 23 24 import java.io.IOException ; 25 import java.lang.reflect.Method ; 26 import java.security.Principal ; 27 import java.security.Permission ; 28 import java.security.ProtectionDomain ; 29 import java.security.Policy ; 30 import java.security.CodeSource ; 31 import java.util.Set ; 32 import java.util.List ; 33 34 import javax.security.jacc.WebUserDataPermission ; 35 import javax.security.jacc.PolicyContext ; 36 import javax.security.jacc.WebResourcePermission ; 37 import javax.security.jacc.WebRoleRefPermission ; 38 import javax.security.jacc.PolicyContextException ; 39 import javax.security.auth.Subject ; 40 import javax.servlet.http.HttpServletRequest ; 41 import javax.servlet.http.HttpServletResponse ; 42 43 import org.apache.catalina.Context; 44 import org.apache.catalina.Wrapper; 45 import org.apache.catalina.connector.Request; 46 import org.apache.catalina.connector.Response; 47 import org.apache.catalina.deploy.SecurityConstraint; 48 import org.jboss.logging.Logger; 49 import org.jboss.metadata.WebMetaData; 50 import org.jboss.metadata.SecurityRoleRefMetaData; 51 52 59 public class JaccAuthorizationRealm extends JBossSecurityMgrRealm 60 { 61 static Logger log = Logger.getLogger(JaccAuthorizationRealm.class); 62 63 64 private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container"; 65 66 private static ThreadLocal activeRequest = new ThreadLocal (); 67 private boolean trace; 68 private Policy policy; 69 70 73 private boolean unprotectedResourceDelegation = false; 74 private String securityConstraintProviderClass = ""; 75 76 public JaccAuthorizationRealm() 77 { 78 policy = Policy.getPolicy(); 79 trace = log.isTraceEnabled(); 80 } 81 82 public boolean hasResourcePermission(Request request, Response response, 83 SecurityConstraint[] securityConstraints, Context context) 84 throws IOException 85 { 86 Wrapper servlet = request.getWrapper(); 87 if (servlet != null) 88 { 89 activeRequest.set(getServletName(servlet)); 90 } 91 Principal requestPrincipal = request.getPrincipal(); 92 HttpServletRequest httpRequest = request.getRequest(); 93 String uri = requestURI(request); 94 WebResourcePermission perm = new WebResourcePermission (uri, httpRequest.getMethod()); 95 boolean allowed = checkSecurityAssociation(perm, requestPrincipal); 96 if( trace ) 97 log.trace("hasResourcePermission, perm="+perm+", allowed="+allowed); 98 if( allowed == false ) 99 { 100 response.sendError(HttpServletResponse.SC_FORBIDDEN, 101 sm.getString("realmBase.forbidden")); 102 } 103 return allowed; 104 } 105 106 public boolean hasRole(Principal principal, String name) 107 { 108 String servletName = (String ) activeRequest.get(); 110 WebMetaData metaData = (WebMetaData) SecurityAssociationValve.activeWebMetaData.get(); 111 List roleRefs = metaData.getSecurityRoleRefs(servletName); 112 String roleName = name; 113 int len = roleRefs != null ? roleRefs.size() : 0; 114 for(int n = 0; n < len; n ++) 115 { 116 SecurityRoleRefMetaData ref = (SecurityRoleRefMetaData) roleRefs.get(n); 117 if( ref.getLink().equals(name) ) 118 { 119 roleName = ref.getName(); 120 break; 121 } 122 } 123 124 WebRoleRefPermission perm = new WebRoleRefPermission (servletName, roleName); 125 Principal [] principals = {principal}; 126 Set roles = getPrincipalRoles(principal); 127 if( roles != null ) 128 { 129 principals = new Principal [roles.size()]; 130 roles.toArray(principals); 131 } 132 boolean allowed = checkSecurityAssociation(perm, principals); 133 if( trace ) 134 log.trace("hasRole, perm="+perm+", allowed="+allowed); 135 return allowed; 136 } 137 138 public boolean hasUserDataPermission(Request request, Response response, 139 SecurityConstraint[] constraints) throws IOException 140 { 141 HttpServletRequest httpRequest = request.getRequest(); 142 Principal requestPrincpal = request.getPrincipal(); 143 establishSubjectContext(requestPrincpal); 144 String uri = requestURI(request); 145 WebUserDataPermission perm = new WebUserDataPermission (uri, httpRequest.getMethod()); 146 if( trace ) 147 log.trace("hasUserDataPermission, p="+perm); 148 boolean ok = false; 149 try 150 { 151 Principal [] principals = null; 152 ok = checkSecurityAssociation(perm, principals); 153 } 154 catch(Exception e) 155 { 156 if( trace ) 157 log.trace("Failed to checkSecurityAssociation", e); 158 } 159 160 163 if( ok == false ) 164 ok = super.hasUserDataPermission(request, response, constraints); 165 return ok; 166 } 167 168 172 public String getSecurityConstraintProviderClass() 173 { 174 return securityConstraintProviderClass; 175 } 176 177 181 public void setSecurityConstraintProviderClass(String securityConstraintProviderClass) 182 { 183 this.securityConstraintProviderClass = securityConstraintProviderClass; 184 } 185 186 192 public boolean isUnprotectedResourceDelegation() 193 { 194 return unprotectedResourceDelegation; 195 } 196 197 203 public void setUnprotectedResourceDelegation(boolean unprotectedResourceDelegation) 204 { 205 this.unprotectedResourceDelegation = unprotectedResourceDelegation; 206 } 207 208 211 public SecurityConstraint[] findSecurityConstraints(Request request, Context context) 212 { 213 SecurityConstraint[] scarr = super.findSecurityConstraints(request, context); 214 if( (scarr == null || scarr.length == 0) 215 && this.unprotectedResourceDelegation) 216 { 217 scarr = getSecurityConstraintsFromProvider(request, context); 218 } 219 return scarr; 220 } 221 222 231 private boolean checkSecurityAssociation(Permission perm, Principal requestPrincpal) 232 { 233 Subject caller = establishSubjectContext(requestPrincpal); 235 236 Principal [] principals = null; 238 if( caller != null ) 239 { 240 if( trace ) 241 log.trace("No active subject found, using "); 242 Set principalsSet = caller.getPrincipals(); 243 principals = new Principal [principalsSet.size()]; 244 principalsSet.toArray(principals); 245 } 246 return checkSecurityAssociation(perm, principals); 247 } 248 257 private boolean checkSecurityAssociation(Permission perm, Principal [] principals) 258 { 259 CodeSource webCS = (CodeSource ) JaccContextValve.activeCS.get(); 260 ProtectionDomain pd = new ProtectionDomain (webCS, null, null, principals); 261 boolean allowed = policy.implies(pd, perm); 262 if( trace ) 263 { 264 String msg = (allowed ? "Allowed: " : "Denied: ") +perm; 265 log.trace(msg); 266 } 267 return allowed; 268 } 269 270 279 private Subject establishSubjectContext(Principal principal) 280 { 281 Subject caller = null; 282 try 283 { 284 caller = (Subject ) PolicyContext.getContext(SUBJECT_CONTEXT_KEY); 285 } 286 catch (PolicyContextException e) 287 { 288 if( trace ) 289 log.trace("Failed to get subject from PolicyContext", e); 290 } 291 292 if( caller == null ) 293 { 294 if( principal instanceof JBossGenericPrincipal ) 296 { 297 JBossGenericPrincipal jgp = (JBossGenericPrincipal) principal; 298 caller = jgp.getSubject(); 299 if (trace) 301 log.trace("Restoring principal info from cache"); 302 SecurityAssociationActions.setPrincipalInfo(jgp.getAuthPrincipal(), 303 jgp.getCredentials(), jgp.getSubject()); 304 } 305 } 306 return caller; 307 } 308 309 327 private String getServletName(Wrapper servlet) 328 { 329 String [] mappings = servlet.findMappings(); 331 if(trace) 332 log.trace("[getServletName:servletmappings="+mappings + 333 ":servlet.getName()="+servlet.getName()+"]"); 334 if("jsp".equals(servlet.getName()) 335 && (mappings != null && mappings[0].indexOf("*.jsp")> -1)) 336 return ""; 337 else 338 return servlet.getName(); 339 } 340 341 349 private SecurityConstraint[] getSecurityConstraintsFromProvider(Request request, Context context) 350 { 351 SecurityConstraint[] scarr = null; 352 Class [] sig = {Request .class, Context .class}; 353 Object [] args = {request, context}; 354 355 Method findsc = null; 356 357 try 359 { 360 findsc = policy.getClass().getMethod("findSecurityConstraints", sig); 361 scarr = (SecurityConstraint[])findsc.invoke(policy, args); 362 }catch(Throwable t) 363 { 364 if(trace) 365 log.error("Error obtaining security constraints from policy",t); 366 } 367 if(scarr == null || scarr.length == 0) 370 { 371 if(securityConstraintProviderClass == "" || 372 securityConstraintProviderClass.length() == 0) 373 { 374 if(trace) 375 log.trace("unprotectedResourceDelegation is true "+ 376 "but securityConstraintProviderClass is empty"); 377 } 378 else 379 try 381 { 382 Class clazz = Thread.currentThread().getContextClassLoader().loadClass(securityConstraintProviderClass); 383 Object obj = clazz.newInstance(); 384 findsc = clazz.getMethod("findSecurityConstraints", sig); 385 if(trace) 386 log.trace("findSecurityConstraints method found in securityConstraintProviderClass"); 387 scarr = (SecurityConstraint[])findsc.invoke(obj, args); 388 } 389 catch (Throwable t) 390 { 391 log.error("Error instantiating "+securityConstraintProviderClass,t); 392 } 393 } 394 return scarr; 395 } 396 397 402 static String requestURI(Request request) 403 { 404 String uri = request.getMappingData().requestPath.getString(); 405 if( uri == null || uri.equals("/") ) 406 { 407 uri = ""; 408 } 409 return uri; 410 } 411 412 } 413 | Popular Tags |