1 22 package org.jboss.ejb.plugins; 23 24 import org.jboss.ejb.Container; 25 import org.jboss.invocation.Invocation; 26 import org.jboss.metadata.ApplicationMetaData; 27 import org.jboss.metadata.AssemblyDescriptorMetaData; 28 import org.jboss.metadata.BeanMetaData; 29 import org.jboss.metadata.SecurityIdentityMetaData; 30 import org.jboss.security.AuthenticationManager; 31 import org.jboss.security.AuthorizationManager; 32 import org.jboss.security.RealmMapping; 33 import org.jboss.security.RunAsIdentity; 34 import org.jboss.security.SecurityConstants; 35 import org.jboss.security.SecurityContext; 36 import org.jboss.security.SecurityRolesAssociation; 37 import org.jboss.security.SecurityContext.SubjectInfo; 38 import org.jboss.security.audit.AuditContext; 39 import org.jboss.security.audit.AuditEvent; 40 import org.jboss.security.audit.AuditLevel; 41 import org.jboss.security.audit.AuditManager; 42 import org.jboss.security.authorization.AuthorizationContext; 43 import org.jboss.security.authorization.EJBResource; 44 import org.jboss.security.authorization.ResourceKeys; 45 import org.jboss.security.plugins.JBossSecurityContext; 46 import org.jboss.system.Registry; 47 48 import java.security.CodeSource ; 49 import java.security.Principal ; 50 import java.util.HashMap ; 51 import java.util.Map ; 52 import java.util.Set ; 53 import java.lang.reflect.Method ; 54 import javax.security.auth.Subject ; 55 import javax.security.jacc.PolicyContextException ; 56 import javax.ejb.TimedObject ; 57 import javax.ejb.Timer ; 58 59 69 public class SecurityInterceptor extends AbstractInterceptor 70 { 71 74 public interface AuthenticationObserver 75 { 76 final String KEY = "SecurityInterceptor.AuthenticationObserver"; 77 void authenticationFailed(); 78 } 79 80 82 protected AuthenticationManager securityManager; 83 84 protected AuthorizationManager authorizationManager; 85 86 88 protected RealmMapping realmMapping; 89 90 protected RunAsIdentity runAsIdentity; 92 93 protected Map securityRoles; 95 96 protected Map deploymentRoles; 98 99 protected AuthenticationObserver authenticationObserver; 103 104 protected Method ejbTimeout; 105 protected String ejbName = null; 107 protected CodeSource ejbCS = null; 108 111 protected String appSecurityDomain = null; 112 protected String defaultAuthorizationSecurityDomain = SecurityConstants.DEFAULT_EJB_APPLICATION_POLICY; 114 115 118 public void setContainer(Container container) 119 { 120 super.setContainer(container); 121 if (container != null) 122 { 123 BeanMetaData beanMetaData = container.getBeanMetaData(); 124 ApplicationMetaData applicationMetaData = beanMetaData.getApplicationMetaData(); 125 AssemblyDescriptorMetaData assemblyDescriptor = applicationMetaData.getAssemblyDescriptor(); 126 securityRoles = assemblyDescriptor.getSecurityRoles(); 127 deploymentRoles = assemblyDescriptor.getPrincipalVersusRolesMap(); 128 129 SecurityIdentityMetaData secMetaData = beanMetaData.getSecurityIdentityMetaData(); 130 if (secMetaData != null && secMetaData.getUseCallerIdentity() == false) 131 { 132 String roleName = secMetaData.getRunAsRoleName(); 133 String principalName = secMetaData.getRunAsPrincipalName(); 134 135 Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName); 137 runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames); 138 } 139 140 securityManager = container.getSecurityManager(); 141 realmMapping = container.getRealmMapping(); 142 authorizationManager = container.getAuthorizationManager(); 143 144 try 145 { 146 ejbTimeout = TimedObject .class.getMethod("ejbTimeout", new Class []{Timer .class}); 148 } 149 catch (NoSuchMethodException ignore) 150 { 151 } 152 appSecurityDomain = applicationMetaData.getSecurityDomain(); 154 ejbName = beanMetaData.getEjbName(); 155 ejbCS = container.getBeanClass().getProtectionDomain().getCodeSource(); 156 } 157 } 158 159 public void start() throws Exception 161 { 162 super.start(); 163 authenticationObserver = 164 (AuthenticationObserver) Registry.lookup(AuthenticationObserver.KEY); 165 } 166 167 public Object invokeHome(Invocation mi) throws Exception 168 { 169 checkSecurityAssociation(mi); 171 172 176 SecurityActions.pushRunAsIdentity(runAsIdentity); 177 178 try 179 { 180 Object returnValue = getNext().invokeHome(mi); 181 return returnValue; 182 } 183 finally 184 { 185 SecurityActions.popRunAsIdentity(); 186 SecurityActions.popSubjectContext(); 187 SecurityActions.clearSecurityContext(appSecurityDomain); 189 } 190 } 191 192 193 public Object invoke(Invocation mi) throws Exception 194 { 195 checkSecurityAssociation(mi); 197 198 202 SecurityActions.pushRunAsIdentity(runAsIdentity); 203 204 try 205 { 206 Object returnValue = getNext().invoke(mi); 207 return returnValue; 208 } 209 finally 210 { 211 SecurityActions.popRunAsIdentity(); 212 SecurityActions.popSubjectContext(); 213 SecurityActions.clearSecurityContext(appSecurityDomain); 215 } 216 } 217 218 223 private void checkSecurityAssociation(Invocation mi) 224 throws Exception 225 { 226 Principal principal = mi.getPrincipal(); 227 Object credential = mi.getCredential(); 228 boolean trace = log.isTraceEnabled(); 229 230 Method m = mi.getMethod(); 232 boolean containerMethod = m == null || m.equals(ejbTimeout); 233 if ( containerMethod == true || securityManager == null || container == null ) 234 { 235 SecurityActions.pushSubjectContext(principal, credential, null); 237 return; 238 } 239 240 if (realmMapping == null) 241 { 242 throw new SecurityException ("Role mapping manager has not been set"); 243 } 244 245 RunAsIdentity callerRunAsIdentity = SecurityActions.peekRunAsIdentity(); 247 if (callerRunAsIdentity == null) 248 { 249 Subject subject = new Subject (); 251 if (securityManager.isValid(principal, credential, subject) == false) 252 { 253 if (authenticationObserver != null) 255 authenticationObserver.authenticationFailed(); 256 Exception ex = SecurityActions.getContextException(); 258 errorAudit(principal,m.getName(),ex); 259 if( ex != null ) 260 throw ex; 261 String msg = "Authentication exception, principal=" + principal; 263 SecurityException e = new SecurityException (msg); 264 failureAudit(principal,m.getName()); 265 throw e; 266 } 267 else 268 { 269 SecurityActions.pushSubjectContext(principal, credential, subject); 270 establishSecurityContext(securityManager.getSecurityDomain(),principal, credential, subject); 271 successAudit(principal,m.getName()); 272 if (trace) 273 { 274 log.trace("Authenticated principal=" + principal); 275 } 276 } 277 } 278 else 279 { 280 SecurityActions.dupSubjectContext(); 282 } 283 284 Method ejbMethod = mi.getMethod(); 285 if( ejbMethod== null ) 287 return; 288 Subject caller = getContextCallerSubject(); 290 291 SecurityRolesAssociation.setSecurityRoles(this.deploymentRoles); 293 294 final HashMap map = new HashMap (); 295 map.put(ResourceKeys.EJB_NAME ,this.ejbName); 296 map.put(ResourceKeys.EJB_METHOD,ejbMethod); 297 map.put(ResourceKeys.EJB_PRINCIPAL, mi.getPrincipal()); 298 map.put(ResourceKeys.EJB_METHODINTERFACE, mi.getType().toInterfaceString()); 299 map.put(ResourceKeys.EJB_CODESOURCE, ejbCS); 300 map.put(ResourceKeys.CALLER_SUBJECT, caller); 301 map.put(ResourceKeys.AUTHORIZATION_MANAGER,authorizationManager); 302 map.put(ResourceKeys.RUNASIDENTITY, callerRunAsIdentity); 303 map.put(ResourceKeys.EJB_METHODROLES, container.getMethodPermissions(ejbMethod, mi.getType())); 304 305 EJBResource ejbResource = new EJBResource(map); 306 boolean isAuthorized = false; 307 try 308 { 309 int check = authorizationManager.authorize(ejbResource); 310 isAuthorized = (check == AuthorizationContext.PERMIT); 311 authorizationAudit((isAuthorized ? AuditLevel.SUCCESS : AuditLevel.FAILURE) 312 ,ejbResource, null); 313 } 314 catch (Exception e) 315 { 316 isAuthorized = false; 317 if(trace) 318 log.trace("Error in authorization:",e); 319 authorizationAudit(AuditLevel.ERROR,ejbResource,e); 320 } 321 String msg = "Denied: caller=" + caller; 322 if(!isAuthorized) 323 throw new SecurityException (msg); 324 } 325 326 336 private Subject getContextCallerSubject() throws PolicyContextException 337 { 338 344 SecurityActions.pushRunAsIdentity(runAsIdentity); 345 Subject caller = SecurityActions.getContextSubject(); 346 SecurityActions.popRunAsIdentity(); 347 return caller; 348 } 349 350 private void audit(String level, 354 Map contextMap, Exception e) 355 { 356 contextMap.put("Source", getClass().getName()); 357 String secDomain = securityManager.getSecurityDomain(); 358 SecurityContext sc = SecurityActions.getSecurityContext(secDomain); 359 AuditContext ac = sc != null ? sc.getAuditContext() : 360 AuditManager.getAuditContext(secDomain); 361 AuditEvent ae = new AuditEvent(level); 362 ae.setContextMap(contextMap); 363 ae.setUnderlyingException(e); 364 ac.audit(ae); 365 } 366 367 private void successAudit(Principal principal, String methodName) 368 { 369 audit(AuditLevel.SUCCESS,getContextMap(principal, methodName),null); 370 } 371 372 private void failureAudit(Principal principal, String methodName) 373 { 374 audit(AuditLevel.FAILURE,getContextMap(principal, methodName),null); 375 } 376 377 private void errorAudit(Principal principal, 378 String methodName, Exception e) 379 { 380 audit(AuditLevel.ERROR,getContextMap(principal, methodName),e); 381 } 382 383 private void authorizationAudit(String level, EJBResource resource, Exception e) 384 { 385 String exceptionMessage = e != null ? e.getLocalizedMessage() : ""; 388 Map cmap = new HashMap (); 389 cmap.putAll(resource.getMap()); 390 cmap.put("Exception:", exceptionMessage); 391 audit(level,cmap,null); 392 } 393 394 private Map getContextMap(Principal principal, String methodName) 395 { 396 Map cmap = new HashMap (); 397 cmap.put("principal", principal); 398 cmap.put("method", methodName); 399 return cmap; 400 } 401 402 private void establishSecurityContext(String domain, Principal p, Object cred, 404 Subject subject) 405 { 406 JBossSecurityContext jsc = new JBossSecurityContext(domain); 407 SubjectInfo si = jsc.new SubjectInfo(); 408 si.setAuthenticatedSubject(subject); 409 si.setAuthenticationCredential(cred); 410 si.setAuthenticationPrincipal(p); 411 jsc.setSubjectInfo(si); 412 SecurityActions.setSecurityContext(jsc, domain); 413 } 414 } 415 | Popular Tags |