-
1. Re: Unable to get Subject from SecurityAssociation when call
ragavgomatam Aug 22, 2008 9:28 PM (in response to kimbaltrue)Shouldn't you be using
ejbContext.getCallerPrincipal()
from within ejb's ? -
2. Re: Unable to get Subject from SecurityAssociation when call
kimbaltrue Aug 25, 2008 8:53 AM (in response to kimbaltrue)Yes, I am using getCallerPrincipal to get the caller principal, but I need the caller's Subject as well. That's not available in the standard EJB API set, but I need it to get the roll list.
-
3. Re: Unable to get Subject from SecurityAssociation when call
ragavgomatam Aug 25, 2008 10:33 AM (in response to kimbaltrue)I don't think you can get the entire role list. What you can do is to test if the Principal has a given role by using :-
ejbContext.isCallerInRole()
-
4. Re: Unable to get Subject from SecurityAssociation when call
kimbaltrue Aug 25, 2008 10:48 AM (in response to kimbaltrue)When the initial EJB bean is called - it's a EJB 3.0 webservice bean - I'm able to get the current context Subject, and from that I can get the principal sets, and from them I can get the full list of a user's roles.
That's actually working.
The problem occurs when I call another EJB 3.0 bean from the first bean. The second bean seems to have lost the initial security context so that I can't get the context Subject.
As for the isCallerInRole this is only useful when you already know the the role. That's taken care of by the @RolesAllowed annotation so I really don't need to call isCallerInRole. What I'm trying to do is allow for dynamic role based access to specific data elements in the database, and I can only do that if I can pull the user's role list.
Also, I'm concerned that if the Subject context is lost then I might not be able to call from one Application server instance to another using the same security associations. -
5. Re: Unable to get Subject from SecurityAssociation when call
ragavgomatam Aug 25, 2008 10:55 AM (in response to kimbaltrue)Hi,
Got it...Can you please post the code as to how these 2 ejb's are calling each other ? That could perhaps give us clues. -
6. Re: Unable to get Subject from SecurityAssociation when call
kimbaltrue Aug 25, 2008 3:01 PM (in response to kimbaltrue)The first bean is a standard EJB3.0 webservice bean.
@WebService(name = "Reference", serviceName = "Reference", targetNamespace = "http://legion.ccf.org") @SOAPBinding(style = SOAPBinding.Style.DOCUMENT) /* * JBOSS specific security annotations */ @SecurityDomain("tactus-domain") @WebContext(authMethod = "BASIC", contextRoot = "/Legion/Ref", transportGuarantee = "NONE", secureWSDLAccess = false) @Stateless(name = "Reference") @Remote(Reference.class) @Local(Reference.class) @TransactionManagement(TransactionManagementType.BEAN) @Interceptors(TrackingMetrics.class) public class ReferenceWebBean implements ReferenceWeb { protected AdapterRegistry registry = null; protected ReferenceWeb adapter = null; /* (non-Javadoc) * @see org.ccf.legion.ReferenceWeb#getUserRoles() */ @Override public List<String> getUserRoles() { return adapter.getUserRoles(); } }
The adapter object is a simple POJO used to do work. It uses the following code to find the second bean using the JNDI string "Legion/ReferenceBean/local".
The ReferenceWebBean (EJB3.0 #1) is a web service bean and calls other beans to do it's work. The ReferenceBean (EJB3.0 #2) is a stateless EJB bean which accesses the database.private Object findJNDIResource(String mappedName) { Object result = null; try { InitialContext context = new InitialContext(); result = context.lookup(mappedName); } catch (NamingException e) { log.debug(messages.getString("AdapterRegistry.24", mappedName)); // if not found just return null } return result; }
After getting the local inteface to the ReferenceBean (EJB3.0 #2) the adapter calls a method on that bean which then does the following:public List<String> getRoles() { List<String> rolelist = new java.util.ArrayList<String>(); Subject subject = org.jboss.security.SecurityAssociation.getSubject(); if(subject == null) { log.debug("Subject is null"); return rolelist; } Set<SimpleGroup> groups = subject.getPrincipals(SimpleGroup.class); if(groups.isEmpty()) log.debug("No Simple Groups"); else { for(SimpleGroup group : groups) { if(group.getName().compareToIgnoreCase("Roles")==0) { java.util.Enumeration<?> en = group.members(); while(en.hasMoreElements()) { Object obj = en.nextElement(); if(obj instanceof Principal) { String name = ((Principal)obj).getName(); rolelist.add(name); log.debug("Role name = "+name); } else { log.debug("Simple Group Content: " + obj.getClass().getName()); } } } } } return rolelist; }
If I put the above code directly in the webservice bean (ReferenceWebBean or EJB3.0 #1) it works, and returns the roles list. If I put this code in the second EJB3.0 bean (ReferenceBean EJB3.0 #2) where the database connections are then it returns a null for the Subject.
These two beans are in the same EAR file, but different JAR files.
The second EJB3.0 bean (ReferenceBean EJB3.0 #2) looks like this:@Stateless(name = "ReferenceBean") //$NON-NLS-1$ @Remote(Reference.class) @Local(Reference.class) @TransactionManagement(TransactionManagementType.BEAN) @Interceptors(TrackingMetrics.class) public class ReferenceBean extends LegionServiceSupport implements Reference { private static final Log log = LogFactory.getLog(ReferenceBean.class); private static final Messages messages = Messages .getMessages(ReferenceBean.class); @PersistenceContext(unitName = "LegionModel") //$NON-NLS-1$ private EntityManager manager = null;
I hope that helps explain what's going on. The codes a bit more involved than what I've shown, but these are the relevant parts. -
7. Re: Unable to get Subject from SecurityAssociation when call
ragavgomatam Aug 25, 2008 6:48 PM (in response to kimbaltrue)If I put the above code directly in the webservice bean (ReferenceWebBean or EJB3.0 #1) it works, and returns the roles list.
I think this explains it. Can Ejb #1 ReferenceWebBean , have a reference to ReferenceBean and have it annotated @Ejb ? This would make the container inject the ReferenceBean into ReferenceWebBean . Then try to see if you get the Roles inside ReferenceBean . What i suspect is that , when the PoJo calls ReferenceBean , the Subject is lost , in other words not propagated through. Can you have a ReferenceBean reference inside
ReferenceWebBean with @Ejb annotation ? -
8. Re: Unable to get Subject from SecurityAssociation when call
kimbaltrue Aug 26, 2008 9:25 AM (in response to kimbaltrue)So, it's not propigating subject between EJB's if they're called through the interface returned from JNDI, but it is propogating it with injection? I would have thought that the injection reference would have come from JNDI to begin with. Does JBOSS have a parallel reference mechanism with JNDI so that the JNDI reference is different from an injected reference?
It may take some time for me to try this, but if it does work I probably can't depend on it for a long term solution. The code is layered with pluggable components so it's not going to take well to having one EJB hard bound to another through an annotation reference.
Is there some way to enforce subject propigation using an JNDI reference using something like Subect.doAs?