dev@glassfish.java.net

Re: custom SAM using glassfish SSO?

From: JJ Snyder <j.j.snyder_at_oracle.com>
Date: Sat, 22 Sep 2012 13:32:22 -0400

I may have been incorrect in the injection point sample code below. The
way I have it
@Inject
Principal principal;

may still get you the proxy that you can't cast. The more I think about
it the more likely I think this is the case. So you probably have to do

@Inject
MyCustomPrincipal principal;

or even add a qualifier
@Inject
@SomeQualifier
MyCustomPrincipal principl; // in this case the producer must be
annotated with @SomeQualifier too.

I'm going to have to write a test app to see what actually
happens...I'll get back to you.

I'll get back to you on the other issue too.

JJ

On 09/22/2012 11:24 AM, Derek Knapp wrote:
> Thanks for the tip, I will keep this in mind, and look forward to hearing any other suggestions the weld people may have.
>
>
> I am having one more problem with my SAM, which is related to SSO. In app #1, where the user logs in, everything is working properly. But in app #2, I can't get my security-constraint to work properly.
>
> I have a non-secured jsp page that simply prints out the principal, and true/false in the user is in the "users" role, and that is working properly (in both apps).. the problem when I add in a security-constraint, requiring the "users" role.. I just get a blank page returned.
>
> In my SAM, I am simply returning SUCCESS if I see that the user principal is not null (was set by glassfish SSO).
>
> if (requestPolicy.isMandatory())
> {
> log.info(request.getUserPrincipal()); // both of these return what I would expect
> log.info(request.isUserInRole("users"));
>
> if (request.getUserPrincipal() == null)
> {
> try
> {
> log.info("redircting");
> response.sendRedirect("https://login.example.com");
> return AuthStatus.SEND_SUCCESS;
> }
> catch (IOException e1)
> {
> log.error("error redirecting to login", e1);
> }
> }
>
> return AuthStatus.SUCCESS;
> }
>
> If I add in the following code before returning SUCCESS everything works properly.. but I don't really have any way to do this unless I can some how get my custom principal back.. I tried to use the Principal from request.getUserPrincipal, but that means I loose my custom principal, because request.getUserPrincipal returns a class com.sun.enterprise.security.web.integration.WebPrincipal. Everything also works if I remove my SAM from app #2, but then I don't get redirected to my login page properly (which I could solve using a filter, but that doesn't seem like the right solution).
>
> I don't know if this makes sense, so please let me know if it doesn't
>
> try
> {
> handler.handle(new Callback[]{
> new CallerPrincipalCallback(clientSubject, new FreeMarketerUser("test", "test")),
> new GroupPrincipalCallback(clientSubject, new String[] {"cn=users,ou=Groups,dc=example,dc=com"})
> });
> }
> catch (Exception e)
> {
> log.error("error in callback", e);
> }
>
>
>
>
>
>
> On Sep 22, 2012, at 4:56 AM, JJ Snyder<j.j.snyder_at_oracle.com> wrote:
>
>> Be very careful...The injection of the object depends on the scope of the object being injected. So if you're doing this on a servlet make sure you annotate the producer with @RequestScoped. Weld will still build a proxy but this time you will be able to cast the proxy to the type returned by the producer. So if your producer is:
>>
>> @Produces
>> @RequestScoped
>> public MyCustomPrincipal getCustomPrincipal() { return howeverYouGetTheCustomPrincipal; }
>>
>> And your injection point is:
>> @Inject
>> Principal principal;
>>
>> private void someMethod() {
>> // this cast works because the weld proxy is typed to the return type of the producer
>> MyCustomPrincipal mcp = (MyCustomPrincipal) principal;
>>
>> // you could also inject like this and then you wouldn't have to cast
>> // @Inject
>> // MyCustomPrincipal principal;
>>
>> }
>>
>>
>> I will ask the weld people if they have any other suggestions.
>>
>> JJ
>>
>>
>> On 09/21/2012 10:46 PM, Derek Knapp wrote:
>>> I have tried casting, and it does not work.
>>>
>>> I was able to look up the SessionContext, and call getCallerPrincipal which returned my custom principal.. I will likely wrap this logic, and add a @Produces annotation so I can directly @Inject my custom principal. if anyone has a better way to get my custom principal, please let me know.
>>>
>>>
>>> Derek
>>>
>>> On Sep 21, 2012, at 7:20 AM, JJ Snyder<j.j.snyder_at_oracle.com> wrote:
>>>
>>>> Derek,
>>>> Weld, the CDI container, creates a proxy (org.jboss.weld.security.Principal) to the current caller principal (your custom principal). The proxy is always injected so that it can delegate the method calls to the current caller principal. I have not tried it and I doubt it will work but you might be able to cast to your custom type.
>>>>
>>>> JJ
>>>>
>>>> On 09/21/2012 04:44 AM, Derek Knapp wrote:
>>>>> Is it possible to @Inject my custom principal in to an ejb?
>>>>>
>>>>> It seems that when I inject a principal using,
>>>>>
>>>>> @Inject
>>>>> private Principal principal;
>>>>>
>>>>> it returns a org.jboss.weld.security.Principal, which seems to wrap my custom principal (I say this because the toString method uses my custom principal's toString)
>>>>>
>>>>> Normally this wouldn't matter, but I actually have some custom data I was hoping to access.
>>>>>
>>>>>
>>>>> Derek
>>>>>
>>>>> On Sep 17, 2012, at 11:27 AM, Ron Monzillo<ron.monzillo_at_oracle.com> wrote:
>>>>>
>>>>>> On 9/17/12 10:38 AM, Derek Knapp wrote:
>>>>>>> Is there any way for my custom SAM to use glassfish's build in SSO abilities?
>>>>>>>
>>>>>>> If not, anyone have any experience doing SSO across multiple applications with a custom SAM?
>>>>>> Derek,
>>>>>>
>>>>>>
>>>>>> Yes, by using a proprietary extension to the Servlet Profile of JASPIC, a SAM can tell the Glassfish
>>>>>> Servlet container to "register" an authentication session.
>>>>>>
>>>>>> From validateRequest, and after having used the container callback handler to
>>>>>> set the caller identity, the SAM would return the following key value pair in the MessageInfo (map)
>>>>>>
>>>>>> key = "com.sun.web.RealmAdapter.register"
>>>>>> value = "true"
>>>>>>
>>>>>> Then when the SAM returns to the container, with return value AuthStatus.SUCCESS,
>>>>>> the container will bind the request to a container authentication session.
>>>>>>
>>>>>> Ron