-
1. Re: Security, testing, and embbedable ejb3
kabirkhan Nov 10, 2005 2:18 PM (in response to dunks80)In the ejb3-interceptors-aop.xml file that comes with the embedded distribution, you'll find a couple of occurrances of:
<bind pointcut="execution(* @org.jboss.annotation.security.SecurityDomain->*(..))"> <interceptor-ref name="org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorFactory"/> </bind>
Try commenting these out -
2. Re: Security, testing, and embbedable ejb3
dunks80 Nov 11, 2005 10:17 AM (in response to dunks80)Thanks Kabir! You totally pointed me in the right direction. I went ahead and extended the AuthernticationInterceptorFactory (and then bound it in the ejb3-interceptors-aop.xml file) to actualy create the jaas subcontext in the jndi tree and then place a custom authentication manager (extension of JaasAuthenticationManager) in it. In my baseTest i have a login function that calls my custom authentication service which my login module usually calls so that i can get back my custom principal. I push that principal onto the SubjectContext along with the password and now I can call my ejbs from within my test environment with all the security bells and whistles in place!
-
3. Re: Security, testing, and embbedable ejb3
ramazanyich Nov 17, 2005 6:29 AM (in response to dunks80)Hi dunks,
Is it possible to share your code ? because I struggle with the same problem.
Thanks -
4. Re: Security, testing, and embbedable ejb3
dunks80 Nov 17, 2005 9:34 AM (in response to dunks80)Yeah here you go. Hopefully this will work for you as well.
import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameAlreadyBoundException; import javax.naming.NamingException; import org.jboss.annotation.security.SecurityDomain; import org.jboss.aop.Advisor; import org.jboss.ejb3.Container; import org.jboss.ejb3.security.Ejb3AuthenticationInterceptor; import org.jboss.security.AuthenticationManager; /** * A extension of jboss's standard AuthenticationInterceptorFactory which will created * the jaas subcontext and bind a TestJaasAuthenticationManager in it. * * @author Galen Dunkleberger (galendunkleberger@gmail.com) * */ public class AuthenticationInterceptorFactory extends org.jboss.ejb3.security.AuthenticationInterceptorFactory { private boolean JAAS_BOUND=false; public AuthenticationInterceptorFactory() { super(); } @Override public Object createPerClass(Advisor advisor) { Object domain=null; try { Container container = (Container)advisor; InitialContext ctx = container.getInitialContext(); SecurityDomain securityAnnotation = (SecurityDomain) advisor.resolveAnnotation(SecurityDomain.class); if (securityAnnotation != null) { domain = new TestJaasAuthenticationManager(securityAnnotation.value(),new TestSecurityAssociationHandler()); try { if(!JAAS_BOUND) { Context jaas=ctx.createSubcontext("java:jaas"); jaas.bind("insight",domain); JAAS_BOUND=true; } } catch(NameAlreadyBoundException e){} } } catch (NamingException e) { throw new RuntimeException(e); } AuthenticationManager manager = (AuthenticationManager) domain; return new Ejb3AuthenticationInterceptor(manager); } @Override public String getName() { return getClass().getName(); } }
import java.io.Serializable; import org.jboss.security.plugins.JaasSecurityManager; import org.jboss.util.TimedCachePolicy; /** * A extension of jboss's standard JaasSecurityManager it simply implements serialziable * (because the jndi bind was complaining if i just tried to insert a normal JaasSecurityManager) * and it's constuctor sets a new TimedCachePolicy * * @author Galen Dunkleberger (galendunkleberger@gmail.com) * */ public class TestJaasAuthenticationManager extends JaasSecurityManager implements Serializable { /** * */ private static final long serialVersionUID = 6677937424769496355L; public TestJaasAuthenticationManager(String securityDomain, TestSecurityAssociationHandler handler) { super(securityDomain, handler); TimedCachePolicy cachePolicy=new TimedCachePolicy(); cachePolicy.create(); cachePolicy.start(); setCachePolicy(cachePolicy); } }
import java.io.Serializable; import java.security.Principal; import org.jboss.security.auth.callback.SecurityAssociationHandler; /** * * A extension of jboss's standard SecurityAssociationHandler it simply implements serialziable * (because the jndi bind or the TestJaasAuthenticationManager was complaining if i just tried to * insert a TestJaasAuthenticationManager which took a normal SecurityAssociationHandler) * @author Galen Dunkleberger (galendunkleberger@gmail.com) * * */ public class TestSecurityAssociationHandler extends SecurityAssociationHandler implements Serializable { public TestSecurityAssociationHandler() { super(); } public TestSecurityAssociationHandler(Principal principal, Object credential) { super(principal, credential); } }
I did not write this next class the source can be found in jboss head i simply made my version public so my base test class (in a differernt package) could access it.import java.lang.reflect.UndeclaredThrowableException; import java.security.AccessController; import java.security.Principal; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import javax.security.auth.Subject; import javax.security.jacc.PolicyContext; import javax.security.jacc.PolicyContextException; import org.jboss.logging.Logger; import org.jboss.security.RunAsIdentity; import org.jboss.security.SecurityAssociation; /** A collection of privileged actions for this package * @author Scott.Stark@jboss.org * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a> * @version $Revison: $ */ public class SecurityActions { private static final Logger log = Logger.getLogger(SecurityActions.class); interface PrincipalInfoAction { PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction() { public void push(final Principal principal, final Object credential, final Subject subject) { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { SecurityAssociation.pushSubjectContext(subject, principal, credential); return null; } } ); } public void pop() { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { SecurityAssociation.popSubjectContext(); return null; } } ); } public Principal getPrincipal() { return (Principal)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { SecurityAssociation.getPrincipal(); return null; } } ); } public Object getCredential() { return AccessController.doPrivileged( new PrivilegedAction() { public Object run() { SecurityAssociation.getCredential(); return null; } } ); } }; PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction() { public void push(Principal principal, Object credential, Subject subject) { SecurityAssociation.pushSubjectContext(subject, principal, credential); } public void pop() { SecurityAssociation.popSubjectContext(); } public Principal getPrincipal() { return SecurityAssociation.getPrincipal(); } public Object getCredential() { return SecurityAssociation.getCredential(); } }; void push(Principal principal, Object credential, Subject subject); void pop(); Principal getPrincipal(); Object getCredential(); } interface RunAsIdentityActions { RunAsIdentityActions PRIVILEGED = new RunAsIdentityActions() { private final PrivilegedAction peekAction = new PrivilegedAction() { public Object run() { return SecurityAssociation.peekRunAsIdentity(); } }; private final PrivilegedAction popAction = new PrivilegedAction() { public Object run() { return SecurityAssociation.popRunAsIdentity(); } }; public RunAsIdentity peek() { return (RunAsIdentity)AccessController.doPrivileged(peekAction); } public void push(final RunAsIdentity id) { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { SecurityAssociation.pushRunAsIdentity(id); return null; } } ); } public RunAsIdentity pop() { return (RunAsIdentity)AccessController.doPrivileged(popAction); } }; RunAsIdentityActions NON_PRIVILEGED = new RunAsIdentityActions() { public RunAsIdentity peek() { return SecurityAssociation.peekRunAsIdentity(); } public void push(RunAsIdentity id) { SecurityAssociation.pushRunAsIdentity(id); } public RunAsIdentity pop() { return SecurityAssociation.popRunAsIdentity(); } }; RunAsIdentity peek(); void push(RunAsIdentity id); RunAsIdentity pop(); } interface ContextInfoActions { static final String EX_KEY = "org.jboss.security.exception"; ContextInfoActions PRIVILEGED = new ContextInfoActions() { private final PrivilegedAction exAction = new PrivilegedAction() { public Object run() { return SecurityAssociation.getContextInfo(EX_KEY); } }; public Exception getContextException() { return (Exception)AccessController.doPrivileged(exAction); } }; ContextInfoActions NON_PRIVILEGED = new ContextInfoActions() { public Exception getContextException() { return (Exception)SecurityAssociation.getContextInfo(EX_KEY); } }; Exception getContextException(); } interface PolicyContextActions { /** The JACC PolicyContext key for the current Subject */ static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container"; PolicyContextActions PRIVILEGED = new PolicyContextActions() { private final PrivilegedExceptionAction exAction = new PrivilegedExceptionAction() { public Object run() throws Exception { return (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY); } }; public Subject getContextSubject() throws PolicyContextException { try { return (Subject) AccessController.doPrivileged(exAction); } catch(PrivilegedActionException e) { Exception ex = e.getException(); if( ex instanceof PolicyContextException ) throw (PolicyContextException) ex; else throw new UndeclaredThrowableException(ex); } } }; PolicyContextActions NON_PRIVILEGED = new PolicyContextActions() { public Subject getContextSubject() throws PolicyContextException { return (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY); } }; Subject getContextSubject() throws PolicyContextException; } private static class SetServerAction implements PrivilegedAction { static PrivilegedAction ACTION = new SetServerAction(); public Object run() { SecurityAssociation.setServer(); return null; } } public static Principal getPrincipal() { if (System.getSecurityManager() == null) { return PrincipalInfoAction.NON_PRIVILEGED.getPrincipal(); } else { return PrincipalInfoAction.PRIVILEGED.getPrincipal(); } } public static void setServer() { AccessController.doPrivileged(SetServerAction.ACTION); } public static Object getCredential() { if (System.getSecurityManager() == null) { return PrincipalInfoAction.NON_PRIVILEGED.getCredential(); } else { return PrincipalInfoAction.PRIVILEGED.getCredential(); } } public static void pushSubjectContext(Principal principal, Object credential, Subject subject) { if(System.getSecurityManager() == null) { PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject); } else { PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject); } } public static void popSubjectContext() { if(System.getSecurityManager() == null) { PrincipalInfoAction.NON_PRIVILEGED.pop(); } else { PrincipalInfoAction.PRIVILEGED.pop(); } } public static RunAsIdentity peekRunAsIdentity() { if(System.getSecurityManager() == null) { return RunAsIdentityActions.NON_PRIVILEGED.peek(); } else { return RunAsIdentityActions.PRIVILEGED.peek(); } } public static void pushRunAsIdentity(RunAsIdentity principal) { if(System.getSecurityManager() == null) { RunAsIdentityActions.NON_PRIVILEGED.push(principal); } else { RunAsIdentityActions.PRIVILEGED.push(principal); } } public static RunAsIdentity popRunAsIdentity() { if(System.getSecurityManager() == null) { return RunAsIdentityActions.NON_PRIVILEGED.pop(); } else { return RunAsIdentityActions.PRIVILEGED.pop(); } } public static Exception getContextException() { if(System.getSecurityManager() == null) { return ContextInfoActions.NON_PRIVILEGED.getContextException(); } else { return ContextInfoActions.PRIVILEGED.getContextException(); } } public static Subject getContextSubject() throws PolicyContextException { if(System.getSecurityManager() == null) { return PolicyContextActions.NON_PRIVILEGED.getContextSubject(); } else { return PolicyContextActions.PRIVILEGED.getContextSubject(); } } }
Then for the actual call my login method in my base test class looks like this....protected void login(String username,String password)throws Exception { Principal user=/*I make a call to a custom service that my login module usually calls to get the custom principal. You could do the same or build your custom principal manually, or just use SimplePrincipal*/ SecurityActions.setServer(); SecurityActions.pushSubjectContext(user,password,null); }
Now to get embeddable ejb to use this I had to include and auth.conf file in the classpath when i ran my tests and poin tto that file using this jvm arg-Djava.security.auth.login.config
Here is what my auth.conf file sorta looks likeyousecuritydomain{ [any_custom_login_modules sufficient;] org.jboss.security.auth.spi.IdentityLoginModule required; };
Hope that helps it's been working great for me. -
5. Re: Security, testing, and embbedable ejb3
ramazanyich Nov 17, 2005 10:41 AM (in response to dunks80)Thanks dunks !
It works perfectly for me.