Apache Geronimo > Discussion Forums  User List | Dev List | Wiki | Issue Tracker  

security propagation from JAAS context to EJB question

View: New views
5 Messages — Rating Filter:   Alert me  

security propagation from JAAS context to EJB question

by Juergen Weber :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I opened a JAAS LoginContext in a JSP (the JSP runs under <security-constraint>) and called an EJB using a PrivilegedAction with the resulting subject. It looks like the subject is not propagated to the EJB. Also it looks like the currently active web user cannot be gotten by JAAS.
So, it looks like there is a separation between Container authority and JAAS.

Is that behaviour OK?

(the background of all this is we'd like to use <security-constraint> for the web app, but the EJB call be with a technical user. Also, the EJB call is much deeper in the call stack than the authentication of the technical user, so the call should be in a PrivilegedAction with the subject bound).

Thanks,
Juergen

I have put some comments with System.out output into the code

Subject subjectjsp = Subject.getSubject(AccessController.getContext());
System.out.println("JSP subject:" + subjectjsp);
// JSP subject:null. Why isn't this the user logged in to the webapp?

SimpleCallbackHandler handler = new SimpleCallbackHandler("tomcat","tomcat".toCharArray());

LoginContext loginCtx = new LoginContext("geronimo-admin", handler);
loginCtx.login();
Subject subject = loginCtx.getSubject();
Set<Principal> principals = subject.getPrincipals();

System.out.println("principals:" + principals);
// principals:[tomcat, admin, tomcatgroup]

PrivilegedAction action = new PrivilegedAction() {

        public Object run()
        {
                Subject subject = Subject.getSubject(AccessController.getContext());
               
                System.out.println("inner subject:" + subject);
                // inner subject:Subject:
                //        Principal: tomcat
                //        Principal: admin
                //        Principal: tomcatgroup

                Context context;
                try
                {
                        context = new InitialContext();
                       
                        Secured3 secured3 = (Secured3) context.lookup("java:comp/env/ejb/Secured3");
                        String secureMethod = secured3.secureMethod("hello");
                        System.out.println("secureMethod: " + secureMethod);

                // ctx.getCallerPrincipal():
                // secureMethod: Hello hello at Thu Jun 18 13:55:49 CEST 2009 org.apache.openejb.core.stateless.StatelessContext@133b364 you are: org.apache.openejb.core.UnauthenticatedPrincipal@1884ac4


Re: security propagation from JAAS context to EJB question

by djencks :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jun 18, 2009, at 5:28 AM, Juergen Weber wrote:

>
> Hi,
>
> I opened a JAAS LoginContext in a JSP (the JSP runs under
> <security-constraint>) and called an EJB using a PrivilegedAction  
> with the
> resulting subject. It looks like the subject is not propagated to  
> the EJB.
> Also it looks like the currently active web user cannot be gotten by  
> JAAS.
> So, it looks like there is a separation between Container authority  
> and
> JAAS.
>
> Is that behaviour OK?
>
> (the background of all this is we'd like to use <security-
> constraint> for
> the web app, but the EJB call be with a technical user. Also, the  
> EJB call
> is much deeper in the call stack than the authentication of the  
> technical
> user, so the call should be in a PrivilegedAction with the subject  
> bound).

I don't understand exactly what you are trying to do but maybe you  
want to authenicate in a jsp rather than using a built in auth  
method?  And then use the resulting Subject in container managed  
authorization??

The way to do this is to use one of the ContextManager.login methods  
so your Subject gets registered with geronimo, and then tell geronimo  
to use your Subject with

ContextManager.setCallers(subject,subject)

or if you want  to imitate "run-as" functionality

Callers oldCallers = ContextManager.pushSubject(subject);
try {
//dostuff
} finally {
   ContextManager.popCallers(oldCallers);
}

(hopefully I remembered the method names and sigs rightly)

hope this helps

david jencks

>
> Thanks,
> Juergen
>
> I have put some comments with System.out output into the code
>
> Subject subjectjsp =  
> Subject.getSubject(AccessController.getContext());
> System.out.println("JSP subject:" + subjectjsp);
> // JSP subject:null. Why isn't this the user logged in to the webapp?
>
> SimpleCallbackHandler handler = new
> SimpleCallbackHandler("tomcat","tomcat".toCharArray());
>
> LoginContext loginCtx = new LoginContext("geronimo-admin", handler);
> loginCtx.login();
> Subject subject = loginCtx.getSubject();
> Set<Principal> principals = subject.getPrincipals();
>
> System.out.println("principals:" + principals);
> // principals:[tomcat, admin, tomcatgroup]
>
> PrivilegedAction action = new PrivilegedAction() {
>
> public Object run()
> {
> Subject subject = Subject.getSubject(AccessController.getContext());
>
> System.out.println("inner subject:" + subject);
> // inner subject:Subject:
>                //        Principal: tomcat
>                //        Principal: admin
>                //        Principal: tomcatgroup
>
> Context context;
> try
> {
> context = new InitialContext();
>
> Secured3 secured3 = (Secured3)
> context.lookup("java:comp/env/ejb/Secured3");
> String secureMethod = secured3.secureMethod("hello");
> System.out.println("secureMethod: " + secureMethod);
>
> // ctx.getCallerPrincipal():
> // secureMethod: Hello hello at Thu Jun 18 13:55:49 CEST 2009
> org.apache.openejb.core.stateless.StatelessContext@133b364 you are:
> org.apache.openejb.core.UnauthenticatedPrincipal@1884ac4
>
>
> --
> View this message in context: http://www.nabble.com/security-propagation-from-JAAS-context-to-EJB-question-tp24091806s134p24091806.html
> Sent from the Apache Geronimo - Users mailing list archive at  
> Nabble.com.
>

Re: security propagation from JAAS context to EJB question

by Juergen Weber :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David,

yes, you understood right. I want the container to use the currently active JAAS subject for the EJB call.

But, I had hoped that the container automatically would use the currently active JAAS subject.
But this seems not be possible, as I have just found explained in this Websphere docs:
http://publib.boulder.ibm.com/infocenter/wasinfo/v5r1//index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/rsec_jaasauthor.html

Anyway, the API you gave, looks fine, but it seems to be
ContextManager
public static Callers pushNextCaller(Subject nextCaller)

Thanks very much,
Juergen

djencks wrote:
On Jun 18, 2009, at 5:28 AM, Juergen Weber wrote:

>
> Hi,
>
> I opened a JAAS LoginContext in a JSP (the JSP runs under
> <security-constraint>) and called an EJB using a PrivilegedAction  
> with the
> resulting subject. It looks like the subject is not propagated to  
> the EJB.
> Also it looks like the currently active web user cannot be gotten by  
> JAAS.
> So, it looks like there is a separation between Container authority  
> and
> JAAS.
>
> Is that behaviour OK?
>
> (the background of all this is we'd like to use <security-
> constraint> for
> the web app, but the EJB call be with a technical user. Also, the  
> EJB call
> is much deeper in the call stack than the authentication of the  
> technical
> user, so the call should be in a PrivilegedAction with the subject  
> bound).

I don't understand exactly what you are trying to do but maybe you  
want to authenicate in a jsp rather than using a built in auth  
method?  And then use the resulting Subject in container managed  
authorization??

The way to do this is to use one of the ContextManager.login methods  
so your Subject gets registered with geronimo, and then tell geronimo  
to use your Subject with

ContextManager.setCallers(subject,subject)

or if you want  to imitate "run-as" functionality

Callers oldCallers = ContextManager.pushSubject(subject);
try {
//dostuff
} finally {
   ContextManager.popCallers(oldCallers);
}

(hopefully I remembered the method names and sigs rightly)

hope this helps

david jencks
>
> Thanks,
> Juergen
>
> I have put some comments with System.out output into the code
>
> Subject subjectjsp =  
> Subject.getSubject(AccessController.getContext());
> System.out.println("JSP subject:" + subjectjsp);
> // JSP subject:null. Why isn't this the user logged in to the webapp?
>
> SimpleCallbackHandler handler = new
> SimpleCallbackHandler("tomcat","tomcat".toCharArray());
>
> LoginContext loginCtx = new LoginContext("geronimo-admin", handler);
> loginCtx.login();
> Subject subject = loginCtx.getSubject();
> Set<Principal> principals = subject.getPrincipals();
>
> System.out.println("principals:" + principals);
> // principals:[tomcat, admin, tomcatgroup]
>
> PrivilegedAction action = new PrivilegedAction() {
>
> public Object run()
> {
> Subject subject = Subject.getSubject(AccessController.getContext());
>
> System.out.println("inner subject:" + subject);
> // inner subject:Subject:
>                //        Principal: tomcat
>                //        Principal: admin
>                //        Principal: tomcatgroup
>
> Context context;
> try
> {
> context = new InitialContext();
>
> Secured3 secured3 = (Secured3)
> context.lookup("java:comp/env/ejb/Secured3");
> String secureMethod = secured3.secureMethod("hello");
> System.out.println("secureMethod: " + secureMethod);
>
> // ctx.getCallerPrincipal():
> // secureMethod: Hello hello at Thu Jun 18 13:55:49 CEST 2009
> org.apache.openejb.core.stateless.StatelessContext@133b364 you are:
> org.apache.openejb.core.UnauthenticatedPrincipal@1884ac4
>
>
> --
> View this message in context: http://www.nabble.com/security-propagation-from-JAAS-context-to-EJB-question-tp24091806s134p24091806.html
> Sent from the Apache Geronimo - Users mailing list archive at  
> Nabble.com.
>

Re: security propagation from JAAS context to EJB question

by djencks :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jun 18, 2009, at 1:08 PM, Juergen Weber wrote:

>
> David,
>
> yes, you understood right. I want the container to use the currently  
> active
> JAAS subject for the EJB call.
>
> But, I had hoped that the container automatically would use the  
> currently
> active JAAS subject.
> But this seems not be possible, as I have just found explained in this
> Websphere docs:
> http://publib.boulder.ibm.com/infocenter/wasinfo/v5r1//index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/rsec_jaasauthor.html

That applies more to big was than geronmo/was ce....

However, my experience, in line with what I can understand from that  
article, is that the jdk Subject-thread association is extremely  
unreliable.  The last time I experimented with it a few years ago,  
Subject.doAs() worked OK but on return there was no Subject associated  
with the current thread.

In general I would try to always use the javaee security mechanisms  
and not try to do low-level JAAS security stuff in your app such as  
the Subject.doAs().  Mixing container managed and app managed security  
can be risky :-)

AFAIK every server uses its own ThreadLocal scheme to associate  
Subjects and threads.... geronimo's is the ContextManager.

thanks
david jencks

>
> Anyway, the API you gave, looks fine, but it seems to be
> ContextManager
> public static Callers pushNextCaller(Subject nextCaller)
>
> Thanks very much,
> Juergen
>
>
> djencks wrote:
>>
>>
>> On Jun 18, 2009, at 5:28 AM, Juergen Weber wrote:
>>
>>>
>>> Hi,
>>>
>>> I opened a JAAS LoginContext in a JSP (the JSP runs under
>>> <security-constraint>) and called an EJB using a PrivilegedAction
>>> with the
>>> resulting subject. It looks like the subject is not propagated to
>>> the EJB.
>>> Also it looks like the currently active web user cannot be gotten by
>>> JAAS.
>>> So, it looks like there is a separation between Container authority
>>> and
>>> JAAS.
>>>
>>> Is that behaviour OK?
>>>
>>> (the background of all this is we'd like to use <security-
>>> constraint> for
>>> the web app, but the EJB call be with a technical user. Also, the
>>> EJB call
>>> is much deeper in the call stack than the authentication of the
>>> technical
>>> user, so the call should be in a PrivilegedAction with the subject
>>> bound).
>>
>> I don't understand exactly what you are trying to do but maybe you
>> want to authenicate in a jsp rather than using a built in auth
>> method?  And then use the resulting Subject in container managed
>> authorization??
>>
>> The way to do this is to use one of the ContextManager.login methods
>> so your Subject gets registered with geronimo, and then tell geronimo
>> to use your Subject with
>>
>> ContextManager.setCallers(subject,subject)
>>
>> or if you want  to imitate "run-as" functionality
>>
>> Callers oldCallers = ContextManager.pushSubject(subject);
>> try {
>> //dostuff
>> } finally {
>>   ContextManager.popCallers(oldCallers);
>> }
>>
>> (hopefully I remembered the method names and sigs rightly)
>>
>> hope this helps
>>
>> david jencks
>>>
>>> Thanks,
>>> Juergen
>>>
>>> I have put some comments with System.out output into the code
>>>
>>> Subject subjectjsp =
>>> Subject.getSubject(AccessController.getContext());
>>> System.out.println("JSP subject:" + subjectjsp);
>>> // JSP subject:null. Why isn't this the user logged in to the  
>>> webapp?
>>>
>>> SimpleCallbackHandler handler = new
>>> SimpleCallbackHandler("tomcat","tomcat".toCharArray());
>>>
>>> LoginContext loginCtx = new LoginContext("geronimo-admin", handler);
>>> loginCtx.login();
>>> Subject subject = loginCtx.getSubject();
>>> Set<Principal> principals = subject.getPrincipals();
>>>
>>> System.out.println("principals:" + principals);
>>> // principals:[tomcat, admin, tomcatgroup]
>>>
>>> PrivilegedAction action = new PrivilegedAction() {
>>>
>>> public Object run()
>>> {
>>> Subject subject =  
>>> Subject.getSubject(AccessController.getContext());
>>>
>>> System.out.println("inner subject:" + subject);
>>> // inner subject:Subject:
>>>               //        Principal: tomcat
>>>               //        Principal: admin
>>>               //        Principal: tomcatgroup
>>>
>>> Context context;
>>> try
>>> {
>>> context = new InitialContext();
>>>
>>> Secured3 secured3 = (Secured3)
>>> context.lookup("java:comp/env/ejb/Secured3");
>>> String secureMethod = secured3.secureMethod("hello");
>>> System.out.println("secureMethod: " + secureMethod);
>>>
>>> // ctx.getCallerPrincipal():
>>> // secureMethod: Hello hello at Thu Jun 18 13:55:49 CEST 2009
>>> org.apache.openejb.core.stateless.StatelessContext@133b364 you are:
>>> org.apache.openejb.core.UnauthenticatedPrincipal@1884ac4
>>>
>>>
>>> --
>>> View this message in context:
>>> http://www.nabble.com/security-propagation-from-JAAS-context-to-EJB-question-tp24091806s134p24091806.html
>>> Sent from the Apache Geronimo - Users mailing list archive at
>>> Nabble.com.
>>>
>>
>>
>
> --
> View this message in context: http://www.nabble.com/security-propagation-from-JAAS-context-to-EJB-question-tp24091806s134p24099592.html
> Sent from the Apache Geronimo - Users mailing list archive at  
> Nabble.com.
>

Re: security propagation from JAAS context to EJB question

by Juergen Weber :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> AFAIK every server uses its own ThreadLocal scheme to associate  
> Subjects and threads....
That's true, and I never liked it, usually it's the only non-portable code of an application.

> geronimo's is the ContextManager.
But Geronimo could be the server that does better in a standard-conforming way.

With the ContextManager way I don't like that it doesn't use the PrivilegedAction pattern.

Couldn't you implement a ContextManager.doAs(Subject, PrivilegedAction) ?

But this would still create a non portable code.
The problem you cited "on return there was no Subject associated  
with the current thread." seems no longer to be there, in my test snippet (see below) the Subject was OK on return.

I believe that on calling an EJB on the client side there is a piece of Geronimo code active. Couldn't that code look with Subject.getSubject(AccessController.getContext()) if there is an active Subject and take that for the EJB call? Maybe one could set a system property to select this behaviour.

The doPrivileged problem cited in
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.zseries.doc/info/zseries/ae/rsec_jaasauthor.html
is still there, but if the programmer knows about it she can avoid using the doPrivileged call.

Thanks,
Juergen

                Subject subjectjsp = Subject.getSubject(AccessController.getContext());
                System.out.println("JSP subject:" + subjectjsp);

                SimpleCallbackHandler handler = new SimpleCallbackHandler("system",
                                "manager".toCharArray());

                LoginContext loginCtx = new LoginContext("geronimo-admin", handler);


                loginCtx.login();
                final Subject subject = loginCtx.getSubject();

                SimpleCallbackHandler handler1 = new SimpleCallbackHandler("tomcat",
                                "tomcat".toCharArray());
                loginCtx = new LoginContext("geronimo-admin", handler1);
                loginCtx.login();
                Subject tomcatsubject = loginCtx.getSubject();


                Set<Principal> principals = subject.getPrincipals();

                System.out.println("principals:" + principals);

                final PrivilegedAction action = new PrivilegedAction()
                {

                        public Object run()
                        {
                                Subject subject = Subject.getSubject(AccessController
                                                .getContext());

                                System.out.println("inner subject:" + subject);

                                Context context;
                                try
                                {

                                        context = new InitialContext();

                                        Secured3 secured3 = (Secured3) context
                                                        .lookup("java:comp/env/ejb/Secured3");

                                        String secureMethod = secured3.secureMethod("hello");
                                        System.out.println("secureMethod: " + secureMethod);
                                }
                                catch (NamingException e1)
                                {
                                        e1.printStackTrace();
                                }

                                return null;
                        }
                };


                Subject.doAs(subject, new java.security.PrivilegedAction()
                {
                        public Object run()
                        {
                                Subject subject0 = Subject.getSubject(AccessController
                                                .getContext());
                                System.out.println("****** start PrivilegedAction.run():"
                                                + subject0);


                                // Subject is associated with the current thread context
                                java.security.AccessController
                                                .doPrivileged(new java.security.PrivilegedAction()
                                                {
                                                        public Object run()
                                                        {
                                                                // Subject was cut off from the current thread
                                                                // context.

                                                                Subject subject1 = Subject
                                                                                .getSubject(AccessController
                                                                                                .getContext());
                                                                System.out
                                                                                .println("****** AccessController.doPrivileged:"
                                                                                                + subject1);

                                                                return null;
                                                        }
                                                });
                                // Subject is associated with the current thread context

                                Subject subject1 = Subject.getSubject(AccessController
                                                .getContext());
                                System.out.println("****** end PrivilegedAction.run():"
                                                + subject1);

                                return null;
                        }
                });


                System.out.println("****** before doAs:"
                                + subject);


                Subject.doAs(tomcatsubject, new PrivilegedAction()
                {
                        public Object run()
                        {


                                Subject.doAs(subject, action);
                               
                                Subject subject1 = Subject.getSubject(AccessController.getContext());
                                System.out.println("****** after doAs tomcatsubject:" + subject1);
                               
                                return null;
                        }
                });

                Subject subject1 = Subject.getSubject(AccessController.getContext());
                System.out.println("****** after inner subject:" + subject1);

        }


djencks wrote:
On Jun 18, 2009, at 1:08 PM, Juergen Weber wrote:

>
> David,
>
> yes, you understood right. I want the container to use the currently  
> active
> JAAS subject for the EJB call.
>
> But, I had hoped that the container automatically would use the  
> currently
> active JAAS subject.
> But this seems not be possible, as I have just found explained in this
> Websphere docs:
> http://publib.boulder.ibm.com/infocenter/wasinfo/v5r1//index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/rsec_jaasauthor.html

That applies more to big was than geronmo/was ce....

However, my experience, in line with what I can understand from that  
article, is that the jdk Subject-thread association is extremely  
unreliable.  The last time I experimented with it a few years ago,  
Subject.doAs() worked OK but on return there was no Subject associated  
with the current thread.

In general I would try to always use the javaee security mechanisms  
and not try to do low-level JAAS security stuff in your app such as  
the Subject.doAs().  Mixing container managed and app managed security  
can be risky :-)

AFAIK every server uses its own ThreadLocal scheme to associate  
Subjects and threads.... geronimo's is the ContextManager.

thanks
david jencks

>
> Anyway, the API you gave, looks fine, but it seems to be
> ContextManager
> public static Callers pushNextCaller(Subject nextCaller)
>
> Thanks very much,
> Juergen
>
>
> djencks wrote:
>>
>>
>> On Jun 18, 2009, at 5:28 AM, Juergen Weber wrote:
>>
>>>
>>> Hi,
>>>
>>> I opened a JAAS LoginContext in a JSP (the JSP runs under
>>> <security-constraint>) and called an EJB using a PrivilegedAction
>>> with the
>>> resulting subject. It looks like the subject is not propagated to
>>> the EJB.
>>> Also it looks like the currently active web user cannot be gotten by
>>> JAAS.
>>> So, it looks like there is a separation between Container authority
>>> and
>>> JAAS.
>>>
>>> Is that behaviour OK?
>>>
>>> (the background of all this is we'd like to use <security-
>>> constraint> for
>>> the web app, but the EJB call be with a technical user. Also, the
>>> EJB call
>>> is much deeper in the call stack than the authentication of the
>>> technical
>>> user, so the call should be in a PrivilegedAction with the subject
>>> bound).
>>
>> I don't understand exactly what you are trying to do but maybe you
>> want to authenicate in a jsp rather than using a built in auth
>> method?  And then use the resulting Subject in container managed
>> authorization??
>>
>> The way to do this is to use one of the ContextManager.login methods
>> so your Subject gets registered with geronimo, and then tell geronimo
>> to use your Subject with
>>
>> ContextManager.setCallers(subject,subject)
>>
>> or if you want  to imitate "run-as" functionality
>>
>> Callers oldCallers = ContextManager.pushSubject(subject);
>> try {
>> //dostuff
>> } finally {
>>   ContextManager.popCallers(oldCallers);
>> }
>>
>> (hopefully I remembered the method names and sigs rightly)
>>
>> hope this helps
>>
>> david jencks
>>>
>>> Thanks,
>>> Juergen
>>>
>>> I have put some comments with System.out output into the code
>>>
>>> Subject subjectjsp =
>>> Subject.getSubject(AccessController.getContext());
>>> System.out.println("JSP subject:" + subjectjsp);
>>> // JSP subject:null. Why isn't this the user logged in to the  
>>> webapp?
>>>
>>> SimpleCallbackHandler handler = new
>>> SimpleCallbackHandler("tomcat","tomcat".toCharArray());
>>>
>>> LoginContext loginCtx = new LoginContext("geronimo-admin", handler);
>>> loginCtx.login();
>>> Subject subject = loginCtx.getSubject();
>>> Set<Principal> principals = subject.getPrincipals();
>>>
>>> System.out.println("principals:" + principals);
>>> // principals:[tomcat, admin, tomcatgroup]
>>>
>>> PrivilegedAction action = new PrivilegedAction() {
>>>
>>> public Object run()
>>> {
>>> Subject subject =  
>>> Subject.getSubject(AccessController.getContext());
>>>
>>> System.out.println("inner subject:" + subject);
>>> // inner subject:Subject:
>>>               //        Principal: tomcat
>>>               //        Principal: admin
>>>               //        Principal: tomcatgroup
>>>
>>> Context context;
>>> try
>>> {
>>> context = new InitialContext();
>>>
>>> Secured3 secured3 = (Secured3)
>>> context.lookup("java:comp/env/ejb/Secured3");
>>> String secureMethod = secured3.secureMethod("hello");
>>> System.out.println("secureMethod: " + secureMethod);
>>>
>>> // ctx.getCallerPrincipal():
>>> // secureMethod: Hello hello at Thu Jun 18 13:55:49 CEST 2009
>>> org.apache.openejb.core.stateless.StatelessContext@133b364 you are:
>>> org.apache.openejb.core.UnauthenticatedPrincipal@1884ac4
>>>
>>>
>>> --
>>> View this message in context:
>>> http://www.nabble.com/security-propagation-from-JAAS-context-to-EJB-question-tp24091806s134p24091806.html
>>> Sent from the Apache Geronimo - Users mailing list archive at
>>> Nabble.com.
>>>
>>
>>
>
> --
> View this message in context: http://www.nabble.com/security-propagation-from-JAAS-context-to-EJB-question-tp24091806s134p24099592.html
> Sent from the Apache Geronimo - Users mailing list archive at  
> Nabble.com.
>