ejb@glassfish.java.net

Re: Design question about EJB and credentials

From: Christopher Piggott <cpiggott_at_gmail.com>
Date: Sun, 15 Jul 2012 21:56:55 -0400

Unfortunately, injecting a Principal didn't work because I had defined
a Provider for the CustomPrincipal in the webapp. I was hoping the
EJB module wouldn't "see" that, but it does:

Error occurred during deployment: Exception while loading the app :
WELD-001409 Ambiguous dependencies for type [Principal] with
qualifiers [@Default] at injection point [[field] @Inject
com.xxxcorp.dao.test.BusinessLogicTestBean.creds]. Possible
dependencies [[Producer Method [XxxUserPrincipal] with qualifiers
[@Any @Default] declared as [[method] @Produces @RequestScoped public
com.xxxscorp.customer.application.SecurityProvider.getuserPrincipal()],
Built-in Bean [java.security.Principal] with qualifiers [@Default]]].

I could fix this by adding a qualifier to my webapp XxxUserPrincipal
provider but I don't particularly want to do that. Maybe I will if I
there is no other way.

Is it possible to declare a @Produces method that's local to just one module?



On Sun, Jul 15, 2012 at 7:02 PM, Chase <chase_at_osdev.org> wrote:
> To inject a Principal you just:
> @Inject private java.security.Principal principal;
>
> But I don't know if it would be your custom principal in the EJB tier.
>
> What about using an EJB interceptor to determine and obtain all the
> extra data like the db connection and then placing it in the
> SessionContext or some CDI managed bean that could be injected
> wherever you need it in the EJB tier? So instead of trying to
> propagate the data from the web tier you are using the regular
> principle to identify the user and then creating the extra data in the
> ejb tier.
>
> -Chase
>
> On Sun, Jul 15, 2012 at 8:36 AM, Christopher Piggott <cpiggott_at_gmail.com> wrote:
>> Hi,
>>
>> I have a design question and am looking for some other peoples
>> thoughts on best practices.
>>
>> In one applicaiton (deployed as an .ear) I have a number of projects:
>> * customer-webapp is a war and is jax-rs (jersey)
>> * customer-object-model is a bunch of jaxb-annotated beans
>> * business-logic contains both logic + persistence (will be split out later)
>>
>> Not part of the ear:
>> * glassfish-auth: a custom AppservRealm and
>> AppservPasswordLoginModule for glassfish
>>
>> My authentication layer does the usual thing, but it attaches my own
>> custom Principal to the Subject. This Principal has extra data
>> associated with it (beyond just Principal and Groups). This
>> information includes a pointer to a specific database associated with
>> that login, as well as some other information about the customer.
>>
>> In the webapp I get the Principal from SecurityContext (a jax-rs
>> class), then if possible safely upcast it to my own Principal.
>>
>> The question is: what's the best way to get this to the EJB layer?
>>
>>
>> Things I have tried:
>>
>> 1. Create a provider method, in the webapp, to retrieve the
>> CustomerPrincipal from the SecurityContext, then in the bean:
>>
>> @RequestScoped
>> public class BusinessBean {
>> @Inject CustomerPrincipal pal;
>> ...
>> }
>>
>> The terrible thing about this design is that EJB layer can no longer
>> exist without the webapp. Long term I want to be able to remote the
>> EJBs so that other applications can make use of the common business
>> logic and persistence.
>>
>>
>> 2. Try to get the Principal injected directly in, but I can't figure
>> out how. SessionContext doesn't seem to apply to RequestScoped beans;
>> RequestContext can't be injected. The only idea I have left is:
>>
>> Subject subject = (Subject)
>> PolicyContext.getContext("javax.security.auth.Subject.container")
>>
>> but this seems hackish (?)
>>
>> 3. The other idea I had was that I could simply require all users to
>> pass the extra information into the business logic beans as properties
>> (i.e. setCustomer(x), setYourDatabase(y). This doesn't seem to fit
>> the pattern, though, requiring the callers to do stuff beyond what I
>> would normally expect them to have to know about. The caller just
>> wants to say "Hi, I'm Fred, and I want you to store this thing." I
>> would expect the business logic side to be responsible for figuring
>> out where to store it, in the most efficient manner possible.
>>
>>
>> Does anybody have any experience with patterns/best practices that
>> relate to this?
>>
>> --Chris