You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@karaf.apache.org by Niels Bertram <ni...@gmail.com> on 2015/01/18 13:29:51 UTC

Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

I am trying to get the contexts Principal from the AccessControlContext as
documented on stackexchange
<http://stackoverflow.com/questions/20970380/get-current-user-in-an-osgi-context-fuse-karaf>
.

Unfortunately whenever I retrieve the subject using the current
AccessControlContext, the subject is null.

I basically create a very simple jaxrs server and register the CXF
JAASAuthenticationFilter with the server:

<bean id="authenticationFilter"
class="org.apache.cxf.jaxrs.security.JAASAuthenticationFilter">
    <property name="contextName" value="karaf" />
</bean>

<jaxrs:server id="echoResource" address="/rest/echo">
    <jaxrs:serviceBeans>
        <bean class="org.apache.karaf.jaas.modules.mongo.test.EchoServiceImpl"
/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <ref component-id="authenticationFilter" />
    </jaxrs:providers>
</jaxrs:server>

When I execute the REST service, I try to get the Subject in the code as
below but it is always null:

AccessControlContext acc = AccessController.getContext();if (acc == null) {
  throw new RuntimeException("access control context is null");
}
Subject subject = Subject.getSubject(acc);if (subject == null) {
  throw new RuntimeException("subject is null");
}

Interestingly if I inject the javax.ws.rs.core.SecurityContext into the CXF
REST service, I do get a security principal.

public Response echo(@Context SecurityContext context) {
   Principal user = context.getUserPrincipal();
}

Is there another configuration required in Karaf or is this a bug in either
Karaf or CXF? Would love to hear if anyone else came across this.

Cheers, Niels

BTW: I tried the same in karaf 2.3.9, 2.4.1 and 3.0.2 with exact same
result.

Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Christian Schneider <ch...@die-schneider.net>.
I dont think the JAASAuthenticationFilter is a good place for this.
Returning a 401 response is common to SOAP and REST while the 
JAASAuthenticationFilter is REST only. I think the response should be 
either generated in the http transport or in a separate interceptor like 
Sergey suggested.

I am not yet sure what I would suggest as a solution. I have to think a 
bit more about it and experiment some more. The difficult thing will be 
to find a solution that covers more than the username/password cases we 
currently look at.

In any case I am quite sure what causes the NPE. It probably happens 
because we have no credentials. I am quite sure this can be fixed easily 
either in karaf (LoginModule) or in the CallbackHandler where we supply 
the credentials.

Christian

Am 20.01.2015 um 11:41 schrieb Niels Bertram:
> Hi Christian, it would probably be better to add the doAs option to 
> the JAASAuthenticationFilter and fix whatever is causing the NPE 
> rather than trying to make the JAASLoginInterceptor do things it may 
> not be designed to do. I'll add some thoughts to the JIRA.
>
> Thanks for the efforts,
> Niels


-- 
  
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
Talend Application Integration Division http://www.talend.com


Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Christian Schneider <ch...@die-schneider.net>.
I now also fixed the NPE in karaf PropertiesLoginModule. See: 
https://issues.apache.org/jira/browse/KARAF-3459

Christian

On 20.01.2015 11:41, Niels Bertram wrote:
> Hi Christian, it would probably be better to add the doAs option to 
> the JAASAuthenticationFilter and fix whatever is causing the NPE 
> rather than trying to make the JAASLoginInterceptor do things it may 
> not be designed to do. I'll add some thoughts to the JIRA.
>
> Thanks for the efforts,
> Niels


-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Niels Bertram <ni...@gmail.com>.
Hi Christian, it would probably be better to add the doAs option to the
JAASAuthenticationFilter and fix whatever is causing the NPE rather than
trying to make the JAASLoginInterceptor do things it may not be designed to
do. I'll add some thoughts to the JIRA.

Thanks for the efforts,
Niels

Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Christian Schneider <ch...@die-schneider.net>.
The current JAASLoginInterceptor has only a very simple handling of the 
authentication error. We know that this should be improved.

I have experimented a bit with some changes in http and core to turn an 
AuthenticationException into a proper http unauthorized response. I am 
unsure how to handle some cases though.
So for example the JAASLoginInterceptor can also handle a WSS Security 
UserNameToken. In this case though I guess we would not like to return a 
401.

I opened an issue https://issues.apache.org/jira/browse/CXF-6206 to 
track this. You are welcome to help define the best solution. We have to 
make this quite solid before doing actual changes to not disturb other 
cases.

Christian

On 20.01.2015 01:14, Niels Bertram wrote:
>
> Hi Christian,
>
> Using authz actually does not make any difference to the response 
> someone will get when not authenticated. The 
> |JAASAuthenticationFilter| will continue to press for credentials with 
> a HTTP 401 response code. Where the |JAASAuthenticationFeature| will 
> just fail with an ugly error message and a 500 server error.
>
> For sanity I took your Karaf-Tutorial and added a few REST annotations 
> to the JAXWS service and also wedged a jaxrs:server configuration into 
> the blueprint. Authentication and authorization seems to work ok as 
> long as there is a valid auth header in the HTTP request:
>
> $ curl -H"Accept: application/json"  -X GET -u karaf:karafhttp://localhost:8181/cxf/rest/person
> {"person":[{"id":1,"name":"Chris"}]}
>
> But trying to access the resource unauthenticated and asking to get a 
> |application/json| response explicitly the only thing I get back is a 
> bunch of XML garbage:
>
> $ curl -H"Accept: application/json"  -X GEThttp://localhost:8181/cxf/rest/person
> <ns1:XMLFault xmlns:ns1="http://cxf.apache.org/bindings/xformat"><ns1:faultstring xmlns:ns1="http://cxf.apache.org/bindings/xformat">org.apache.cxf.interceptor.security.AuthenticationException: Authentication required but no user or password was supplied</ns1:faultstring></ns1:XMLFault>
>
> Here I would expect a HTTP 401 response instead of XML and a HTTP 500 
> Server Error. As said before, for a proper REST experience one would 
> need to use |JAASAuthenticationFilter| but this component should not 
> be disabling the |useDoAs| on the |JAASLoginInterceptor|.
>
> Cheers,
> Niels
>
>
>
>
> On Mon, Jan 19, 2015 at 11:10 PM, Christian Schneider 
> <chris@die-schneider.net <ma...@die-schneider.net>> wrote:
>
>     Have you tried to use only the |JAASAuthenticationFeature|
>     together with blueprint authz for Rest?
>
>     Maybe it works better.
>
>     Christian
>


-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Niels Bertram <ni...@gmail.com>.
Hi Christian,

Using authz actually does not make any difference to the response someone
will get when not authenticated. The JAASAuthenticationFilter will continue
to press for credentials with a HTTP 401 response code. Where the
JAASAuthenticationFeature will just fail with an ugly error message and a
500 server error.

For sanity I took your Karaf-Tutorial and added a few REST annotations to
the JAXWS service and also wedged a jaxrs:server configuration into the
blueprint. Authentication and authorization seems to work ok as long as
there is a valid auth header in the HTTP request:

$ curl -H "Accept: application/json" -X GET -u karaf:karaf
http://localhost:8181/cxf/rest/person
{"person":[{"id":1,"name":"Chris"}]}

But trying to access the resource unauthenticated and asking to get a
application/json response explicitly the only thing I get back is a bunch
of XML garbage:

$ curl -H "Accept: application/json" -X GET
http://localhost:8181/cxf/rest/person<ns1:XMLFault
xmlns:ns1="http://cxf.apache.org/bindings/xformat"><ns1:faultstring
xmlns:ns1="http://cxf.apache.org/bindings/xformat">org.apache.cxf.interceptor.security.AuthenticationException:
Authentication required but no user or password was
supplied</ns1:faultstring></ns1:XMLFault>

Here I would expect a HTTP 401 response instead of XML and a HTTP 500
Server Error. As said before, for a proper REST experience one would need
to use JAASAuthenticationFilter but this component should not be disabling
the useDoAs on the JAASLoginInterceptor.

Cheers,
Niels



On Mon, Jan 19, 2015 at 11:10 PM, Christian Schneider <
chris@die-schneider.net> wrote:

>  Have you tried to use only the JAASAuthenticationFeature
> together with blueprint authz for Rest?
>
> Maybe it works better.
>
> Christian
>
>

Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Christian Schneider <ch...@die-schneider.net>.
Have you tried to use only the |JAASAuthenticationFeature|
together with blueprint authz for Rest?

Maybe it works better.

Christian

On 19.01.2015 13:43, Niels Bertram wrote:
>
> Actually I was too quick declaring victory. I read through the code of 
> |JAASAuthenticationFeature| and also the JAXRS 
> specific|JAASAuthenticationFilter| I have been using. Both actually 
> delegate to the |JAASLoginInterceptor| and hence one should use one OR 
> the other.
>
> Adding both will simply make the |JAASLoginInterceptor| registered as 
> a provider in the |JAASAuthenticationFeature| take precedence over the 
> REST |JAASAuthenticationFilter|. The |JAASLoginInterceptor| will not 
> redirect with a 401 in REST style but just fail with an awful error 
> message.
>
> Interestingly the secret to the |JAASAuthenticationFilter| not being 
> able to set the underlying security context is this line in the 
> constructor of the REST filter (JAASAuthenticationFilter.java:66 3.0.2):
>
> interceptor.setUseDoAs(false);
>
> This will effectively disable the execution of the remainder of the 
> exchange under a privileged action that creates the 
> AccessControlContext as per |JAASLoginInterceptor.java:139|.
>
> if  (useDoAs) {
>    Subject.doAs(subject,new  PrivilegedAction<Void>() {
>    ...
>
> When I sheepishly change the value of the |setUseDoAs| to true during 
> the object instantiation in the filter, the whole execution fails with 
> below stack trace. So something in the CXF JAXRS filtering mechanism 
> is broken that would set 
> parameter|org.apache.cxf.jaxrs.model.OperationResourceInfo| on the 
> exchange.
>
> The line that fails with the NPE is |JAXRSInvoker.java:358|
>
> OperationResourceInfo  ori=  exchange.get(OperationResourceInfo.class);
>
> Looks like a bug in the CXF JAXRS implementation if you ask me. Or it 
> is inherently not possible due to the JAXRS filter being executed 
> inside the `JAXRSInInterceptor` itself. I think I need to move this 
> discussion to the CXF mailing list.
>
> |2015-01-19 22:05:24,527 | INFO  | qtp2023231351-73 | LoggingInInterceptor             | 80 - org.apache.cxf.cxf-core - 3.0.2 | Inbound Message
> ----------------------------
> ID: 51
> Address:http://localhost:8181/cxf/echo/jaas/t1
> Http-Method  <http://localhost:8181/cxf/echo/jaas/t1%0AHttp-Method>: GET
> Content-Type:
> Headers: {Accept=[*/*], Authorization=[Basic a2FyYWY6a2FyYWY=], Content-Type=[null], Host=[localhost:8181], User-Agent=[curl/7.28.1]}
> --------------------------------------
> 2015-01-19 22:05:48,066 | WARN  | qtp2023231351-73 | PhaseInterceptorChain            | 80 - org.apache.cxf.cxf-core - 3.0.2 | Interceptor for {http://test.jaas.fleurida.com/}EchoServiceImpl  <http://test.jaas.fleurida.com/%7DEchoServiceImpl>  has throw
> n exception, unwinding now
> java.lang.NullPointerException
>          at org.apache.cxf.jaxrs.JAXRSInvoker.getResourceProvider(JAXRSInvoker.java:358)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
>          at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:92)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
>          at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)[80:org.apache.cxf.cxf-core:3.0.2]
>          at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)[80:org.apache.cxf.cxf-core:3.0.2]
>          at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)[80:org.apache.cxf.cxf-core:3.0.2]
>          at org.apache.cxf.interceptor.security.JAASLoginInterceptor$1.run(JAASLoginInterceptor.java:146)[80:org.apache.cxf.cxf-core:3.0.2]
>          at org.apache.cxf.interceptor.security.JAASLoginInterceptor$1.run(JAASLoginInterceptor.java:140)[80:org.apache.cxf.cxf-core:3.0.2]
>          at java.security.AccessController.doPrivileged(Native Method)[:1.7.0_71]
>          at javax.security.auth.Subject.doAs(Subject.java:356)[:1.7.0_71]
>          at org.apache.cxf.interceptor.security.JAASLoginInterceptor.handleMessage(JAASLoginInterceptor.java:140)[80:org.apache.cxf.cxf-core:3.0.2]
>          at org.apache.cxf.jaxrs.security.JAASAuthenticationFilter.filter(JAASAuthenticationFilter.java:111)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
>          at org.apache.cxf.jaxrs.utils.JAXRSUtils.runContainerRequestFilters(JAXRSUtils.java:1624)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
>          at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:106)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
>          at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:77)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
>          at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)[80:org.apache.cxf.cxf-core:3.0.2]
>          at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[80:org.apache.cxf.cxf-core:3.0.2]
>          at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:197)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:290)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:214)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)[84:org.apache.geronimo.specs.geronimo-servlet_3.0_spec:1.0]
>          at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:265)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
>          at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)[89:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
>          at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)[89:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
>          at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:69)[98:org.ops4j.pax.web.pax-web-jetty:3.1.2]
>          at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)[89:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]|
>
>
>
> On Mon, Jan 19, 2015 at 8:16 PM, Niels Bertram <nielsbne@gmail.com 
> <ma...@gmail.com>> wrote:
>
>     Hi Christian,
>
>     oh yes I can see, adding the JAASAuthenticationFeature to the cxf
>     bus is required _in addition _to adding the JAASLoginInterceptor.
>     I was not getting desired result after Phase 1 so that makes sense.
>
>     I added a very simple example to GitHub
>     <https://github.com/bertramn/jaas-auth-rest-example> for anyone
>     interested.
>
>     Thanks a lot for help, much appreciated!
>
>     Kind Regards,
>     Niels
>


-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Niels Bertram <ni...@gmail.com>.
Actually I was too quick declaring victory. I read through the code of
JAASAuthenticationFeature and also the JAXRS specific
JAASAuthenticationFilter I have been using. Both actually delegate to the
JAASLoginInterceptor and hence one should use one OR the other.

Adding both will simply make the JAASLoginInterceptor registered as a
provider in the JAASAuthenticationFeature take precedence over the REST
JAASAuthenticationFilter. The JAASLoginInterceptor will not redirect with a
401 in REST style but just fail with an awful error message.

Interestingly the secret to the JAASAuthenticationFilter not being able to
set the underlying security context is this line in the constructor of the
REST filter (JAASAuthenticationFilter.java:66 3.0.2):

interceptor.setUseDoAs(false);

This will effectively disable the execution of the remainder of the
exchange under a privileged action that creates the AccessControlContext as
per JAASLoginInterceptor.java:139.

if (useDoAs) {
  Subject.doAs(subject, new PrivilegedAction<Void>() {
  ...

When I sheepishly change the value of the setUseDoAs to true during the
object instantiation in the filter, the whole execution fails with below
stack trace. So something in the CXF JAXRS filtering mechanism is broken
that would set parameterorg.apache.cxf.jaxrs.model.OperationResourceInfo on
the exchange.

The line that fails with the NPE is JAXRSInvoker.java:358

OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);

Looks like a bug in the CXF JAXRS implementation if you ask me. Or it is
inherently not possible due to the JAXRS filter being executed inside the
`JAXRSInInterceptor` itself. I think I need to move this discussion to the
CXF mailing list.

2015-01-19 22:05:24,527 | INFO  | qtp2023231351-73 |
LoggingInInterceptor             | 80 - org.apache.cxf.cxf-core -
3.0.2 | Inbound Message
----------------------------
ID: 51
Address: http://localhost:8181/cxf/echo/jaas/t1
Http-Method: GET
Content-Type:
Headers: {Accept=[*/*], Authorization=[Basic a2FyYWY6a2FyYWY=],
Content-Type=[null], Host=[localhost:8181], User-Agent=[curl/7.28.1]}
--------------------------------------
2015-01-19 22:05:48,066 | WARN  | qtp2023231351-73 |
PhaseInterceptorChain            | 80 - org.apache.cxf.cxf-core -
3.0.2 | Interceptor for
{http://test.jaas.fleurida.com/}EchoServiceImpl has throw
n exception, unwinding now
java.lang.NullPointerException
        at org.apache.cxf.jaxrs.JAXRSInvoker.getResourceProvider(JAXRSInvoker.java:358)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:92)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)[80:org.apache.cxf.cxf-core:3.0.2]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)[80:org.apache.cxf.cxf-core:3.0.2]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)[80:org.apache.cxf.cxf-core:3.0.2]
        at org.apache.cxf.interceptor.security.JAASLoginInterceptor$1.run(JAASLoginInterceptor.java:146)[80:org.apache.cxf.cxf-core:3.0.2]
        at org.apache.cxf.interceptor.security.JAASLoginInterceptor$1.run(JAASLoginInterceptor.java:140)[80:org.apache.cxf.cxf-core:3.0.2]
        at java.security.AccessController.doPrivileged(Native Method)[:1.7.0_71]
        at javax.security.auth.Subject.doAs(Subject.java:356)[:1.7.0_71]
        at org.apache.cxf.interceptor.security.JAASLoginInterceptor.handleMessage(JAASLoginInterceptor.java:140)[80:org.apache.cxf.cxf-core:3.0.2]
        at org.apache.cxf.jaxrs.security.JAASAuthenticationFilter.filter(JAASAuthenticationFilter.java:111)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.runContainerRequestFilters(JAXRSUtils.java:1624)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
        at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:106)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
        at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:77)[108:org.apache.cxf.cxf-rt-frontend-jaxrs:3.0.2]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)[80:org.apache.cxf.cxf-core:3.0.2]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[80:org.apache.cxf.cxf-core:3.0.2]
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:197)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:290)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:214)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)[84:org.apache.geronimo.specs.geronimo-servlet_3.0_spec:1.0]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:265)[103:org.apache.cxf.cxf-rt-transports-http:3.0.2]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)[89:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)[89:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:69)[98:org.ops4j.pax.web.pax-web-jetty:3.1.2]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)[89:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]




On Mon, Jan 19, 2015 at 8:16 PM, Niels Bertram <ni...@gmail.com> wrote:

> Hi Christian,
>
> oh yes I can see, adding the JAASAuthenticationFeature to the cxf bus is
> required *in addition *to adding the JAASLoginInterceptor. I was not
> getting desired result after Phase 1 so that makes sense.
>
> I added a very simple example to GitHub
> <https://github.com/bertramn/jaas-auth-rest-example> for anyone
> interested.
>
> Thanks a lot for help, much appreciated!
>
> Kind Regards,
> Niels
>

Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Niels Bertram <ni...@gmail.com>.
Hi Christian,

oh yes I can see, adding the JAASAuthenticationFeature to the cxf bus is
required *in addition *to adding the JAASLoginInterceptor. I was not
getting desired result after Phase 1 so that makes sense.

I added a very simple example to GitHub
<https://github.com/bertramn/jaas-auth-rest-example> for anyone interested.

Thanks a lot for help, much appreciated!

Kind Regards,
Niels



On Mon, Jan 19, 2015 at 6:18 PM, Christian Schneider <
chris@die-schneider.net> wrote:

>  Hi Niels,
>
> this is what you need to configure in blueprint to make it work:
>
> https://github.com/cschneider/Karaf-Tutorial/blob/master/cxf/personservice/server/src/main/resources/OSGI-INF/blueprint/blueprint.xml
>
> I never tested with rest but in SOAP it worked fine and it should also
> work in SOAP.
>
> It works like this:
>
> Phase 1 is the authentication. It is mainly done in the CXF interceptor
>
> - The JAASAuthenticationFeature adds the JAASLoginInterceptor
> - Inside the interceptor the basic auth http headers are read and a JAAS
> login is done
> - During the JAAS login by default the "karaf" context is used. So you can
> login for example with karaf/karaf or whatever you set in you
> users.propeties
> - The following CXF chain is called in subject.doAs. This populates the
> AccessControlContext
>
> From this point on you can use standard JAAS API calls to work with the
> AccessControlContext.
>
> Phase 2 is authorization
>
> As a second step you can then use the blueprint authz module. Simply
> activate it with <authz:enable/>
>
> It works with the @RolesAllowed annotations to secure access to blueprint
> beans.
> In my case I set it on
> https://github.com/cschneider/Karaf-Tutorial/blob/master/cxf/personservice/server/src/main/java/net/lr/tutorial/karaf/cxf/personservice/impl/PersonServiceImpl.java
>
> @RolesAllowed("admin")
> public Person[] getAll() {
> return personMap.values().toArray(new Person[]{});
> }
>
> So this works with the roles set in users.properties. As the user karaf is
> in the group admin he can access the method. If you add another user
> without this role then it will be able to access unsecured methods but not
> this one.
>
> Does this work for you?
>
> Christian
>
>

Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Christian Schneider <ch...@die-schneider.net>.
Hi Niels,

this is what you need to configure in blueprint to make it work:
https://github.com/cschneider/Karaf-Tutorial/blob/master/cxf/personservice/server/src/main/resources/OSGI-INF/blueprint/blueprint.xml

I never tested with rest but in SOAP it worked fine and it should also 
work in SOAP.

It works like this:

Phase 1 is the authentication. It is mainly done in the CXF interceptor

- The JAASAuthenticationFeature adds the JAASLoginInterceptor
- Inside the interceptor the basic auth http headers are read and a JAAS 
login is done
- During the JAAS login by default the "karaf" context is used. So you 
can login for example with karaf/karaf or whatever you set in you 
users.propeties
- The following CXF chain is called in subject.doAs. This populates the 
AccessControlContext

 From this point on you can use standard JAAS API calls to work with the 
AccessControlContext.

Phase 2 is authorization

As a second step you can then use the blueprint authz module. Simply 
activate it with <authz:enable/>

It works with the @RolesAllowed annotations to secure access to 
blueprint beans.
In my case I set it on 
https://github.com/cschneider/Karaf-Tutorial/blob/master/cxf/personservice/server/src/main/java/net/lr/tutorial/karaf/cxf/personservice/impl/PersonServiceImpl.java

@RolesAllowed("admin")
public Person[] getAll() {
return personMap.values().toArray(new Person[]{});
}

So this works with the roles set in users.properties. As the user karaf 
is in the group admin he can access the method. If you add another user 
without this role then it will be able to access unsecured methods but 
not this one.

Does this work for you?

Christian

On 19.01.2015 02:32, Niels Bertram wrote:
>
> Hi Christian,
>
> yes I did give cxf 3.0.3 on Karaf 2.3.9 a try without the desired 
> outcome. After some digging, it appears that the 
> |AccessControlContext| does not have the combiner field populated 
> after a sucessful authentication. There are a few AccessControlContext 
> instances in the heap that have a valid combiner set. These contexts 
> appear to be from the Karaf shell.
>
> The point at which subject retrieval fails is 
> in|javax.security.auth.Subject.getSubject(AccessControlContext 
> acc)| line 300 on JDK 1.7.0_71. Here it expects the 
> AccessControlContext to return a SubjectDomainCombiner but the actual 
> combiner on the AccessControlContext is null and hence it is not able 
> to retieve the security context.
>
> // return the Subject from the DomainCombiner of the provided context
> return  AccessController.doPrivileged
>      (new  java.security.PrivilegedAction<Subject>() {
>      public  Subject  run() {
>          DomainCombiner  dc=  acc.getDomainCombiner();
>          if  (!(dcinstanceof  SubjectDomainCombiner))
>              return  null;
>          SubjectDomainCombiner  sdc=  (SubjectDomainCombiner)dc;
>          return  sdc.getSubject();
>      }
> });
>
> Now I am not sure but I would expect this context to be set by the 
> JAAS framework and not the CXF interceptor. I had a quick look at 
> the authorization blueprint extension but not sure I understand the 
> workings of this test. All I am after is to get the Subject in a 
> simple authenticated REST service call.
>
> Any thoughts or pointers on the above? Looks to me as if something is 
> broken in either Karaf JAAS or the CXF interceptor.
>
> Many thanks,
> Niels
>
>
> On Sun, Jan 18, 2015 at 11:25 PM, Christian Schneider 
> <chris@die-schneider.net <ma...@die-schneider.net>> wrote:
>
>     Did you try with CXF 3.0.2 ? The older versions of CXF did not set
>     the AccessControlContext.
>
>     Btw. if you use Blueprint you can also try the jaas authorization
>     blueprint extension.
>     See
>     https://github.com/apache/aries/blob/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/authz/AuthorizationTest.java
>
>     Christian
>
>     Am 18.01.2015 um 13:29 schrieb Niels Bertram:
>>
>>     I am trying to get the contexts Principal from the
>>     AccessControlContext as documented on stackexchange
>>     <http://stackoverflow.com/questions/20970380/get-current-user-in-an-osgi-context-fuse-karaf>.
>>
>>     Unfortunately whenever I retrieve the subject using the current
>>     AccessControlContext, the subject is null.
>>
>>     I basically create a very simple jaxrs server and register the
>>     CXF JAASAuthenticationFilter with the server:
>>
>>     <bean  id="authenticationFilter"  class="org.apache.cxf.jaxrs.security.JAASAuth
>>     enticationFilter">
>>          <property  name="contextName"  value="karaf"  />
>>     </bean>
>>
>>     <jaxrs:server  id="echoResource"  address="/rest/echo">
>>          <jaxrs:serviceBeans>
>>              <bean  class="org.apache.karaf.jaas.modules.mongo.test.EchoServiceImpl"  />
>>          </jaxrs:serviceBeans>
>>          <jaxrs:providers>
>>              <ref  component-id="authenticationFilter"  />
>>          </jaxrs:providers>
>>     </jaxrs:server>
>>
>>     When I execute the REST service, I try to get the Subject in the
>>     code as below but it is always null:
>>
>>     AccessControlContext  acc=  AccessController.getContext();
>>     if  (acc==  null) {
>>        throw  new  RuntimeException("access control context is null");
>>     }
>>
>>     Subject  subject=  Subject.getSubject(acc);
>>     if  (subject==  null) {
>>        throw  new  RuntimeException("subject is null");
>>     }
>>
>>     Interestingly if I inject the javax.ws.rs.core.SecurityContext
>>     into the CXF REST service, I do get a security principal.
>>
>>     public  Response  echo(@Context  SecurityContext  context) {
>>         Principal  user=  context.getUserPrincipal();
>>     }
>>
>>     Is there another configuration required in Karaf or is this a bug
>>     in either Karaf or CXF? Would love to hear if anyone else came
>>     across this.
>>
>>     Cheers, Niels
>>
>>     BTW: I tried the same in karaf 2.3.9, 2.4.1 and 3.0.2 with exact
>>     same result.
>>
>
>
>     -- 
>       
>     Christian Schneider
>     http://www.liquid-reality.de
>
>     Open Source Architect
>     Talend Application Integration Divisionhttp://www.talend.com  
>
>


-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Niels Bertram <ni...@gmail.com>.
Hi Christian,

yes I did give cxf 3.0.3 on Karaf 2.3.9 a try without the desired outcome.
After some digging, it appears that the AccessControlContext does not have
the combiner field populated after a sucessful authentication. There are a
few AccessControlContext instances in the heap that have a valid combiner
set. These contexts appear to be from the Karaf shell.

The point at which subject retrieval fails is
injavax.security.auth.Subject.getSubject(AccessControlContext
acc) line 300 on JDK 1.7.0_71. Here it expects the AccessControlContext to
return a SubjectDomainCombiner but the actual combiner on the
AccessControlContext is null and hence it is not able to retieve the
security context.

// return the Subject from the DomainCombiner of the provided
contextreturn AccessController.doPrivileged
    (new java.security.PrivilegedAction<Subject>() {
    public Subject run() {
        DomainCombiner dc = acc.getDomainCombiner();
        if (!(dc instanceof SubjectDomainCombiner))
            return null;
        SubjectDomainCombiner sdc = (SubjectDomainCombiner)dc;
        return sdc.getSubject();
    }
});

Now I am not sure but I would expect this context to be set by the JAAS
framework and not the CXF interceptor. I had a quick look at
the authorization blueprint extension but not sure I understand the
workings of this test. All I am after is to get the Subject in a simple
authenticated REST service call.

Any thoughts or pointers on the above? Looks to me as if something is
broken in either Karaf JAAS or the CXF interceptor.

Many thanks,
Niels

On Sun, Jan 18, 2015 at 11:25 PM, Christian Schneider <
chris@die-schneider.net> wrote:

>  Did you try with CXF 3.0.2 ? The older versions of CXF did not set the
> AccessControlContext.
>
> Btw. if you use Blueprint you can also try the jaas authorization
> blueprint extension.
> See
> https://github.com/apache/aries/blob/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/authz/AuthorizationTest.java
>
> Christian
>
> Am 18.01.2015 um 13:29 schrieb Niels Bertram:
>
>  I am trying to get the contexts Principal from the AccessControlContext
> as documented on stackexchange
> <http://stackoverflow.com/questions/20970380/get-current-user-in-an-osgi-context-fuse-karaf>
> .
>
> Unfortunately whenever I retrieve the subject using the current
> AccessControlContext, the subject is null.
>
> I basically create a very simple jaxrs server and register the CXF
> JAASAuthenticationFilter with the server:
>
> <bean id="authenticationFilter" class="org.apache.cxf.jaxrs.security.JAASAuth
> enticationFilter">
>     <property name="contextName" value="karaf" />
> </bean>
>
> <jaxrs:server id="echoResource" address="/rest/echo">
>     <jaxrs:serviceBeans>
>         <bean class="org.apache.karaf.jaas.modules.mongo.test.EchoServiceImpl" />
>     </jaxrs:serviceBeans>
>     <jaxrs:providers>
>         <ref component-id="authenticationFilter" />
>     </jaxrs:providers>
> </jaxrs:server>
>
>  When I execute the REST service, I try to get the Subject in the code as
> below but it is always null:
>
> AccessControlContext acc = AccessController.getContext();if (acc == null) {
>   throw new RuntimeException("access control context is null");
> }
> Subject subject = Subject.getSubject(acc);if (subject == null) {
>   throw new RuntimeException("subject is null");
> }
>
>  Interestingly if I inject the javax.ws.rs.core.SecurityContext into the
> CXF REST service, I do get a security principal.
>
> public Response echo(@Context SecurityContext context) {
>    Principal user = context.getUserPrincipal();
> }
>
>  Is there another configuration required in Karaf or is this a bug in
> either Karaf or CXF? Would love to hear if anyone else came across this.
>
> Cheers, Niels
>
> BTW: I tried the same in karaf 2.3.9, 2.4.1 and 3.0.2 with exact same
> result.
>
>
>
> --
>
> Christian Schneiderhttp://www.liquid-reality.de
>
> Open Source Architect
> Talend Application Integration Division http://www.talend.com
>
>

Re: Security Subject from AccessControlContext is null when using JAAS and CXF JAASAuthenticationFilter

Posted by Christian Schneider <ch...@die-schneider.net>.
Did you try with CXF 3.0.2 ? The older versions of CXF did not set the 
AccessControlContext.

Btw. if you use Blueprint you can also try the jaas authorization 
blueprint extension.
See 
https://github.com/apache/aries/blob/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/authz/AuthorizationTest.java

Christian

Am 18.01.2015 um 13:29 schrieb Niels Bertram:
>
> I am trying to get the contexts Principal from the 
> AccessControlContext as documented on stackexchange 
> <http://stackoverflow.com/questions/20970380/get-current-user-in-an-osgi-context-fuse-karaf>.
>
> Unfortunately whenever I retrieve the subject using the current 
> AccessControlContext, the subject is null.
>
> I basically create a very simple jaxrs server and register the CXF 
> JAASAuthenticationFilter with the server:
>
> <bean  id="authenticationFilter"  class="org.apache.cxf.jaxrs.security.JAASAuthenticationFilter">
>      <property  name="contextName"  value="karaf"  />
> </bean>
>
> <jaxrs:server  id="echoResource"  address="/rest/echo">
>      <jaxrs:serviceBeans>
>          <bean  class="org.apache.karaf.jaas.modules.mongo.test.EchoServiceImpl"  />
>      </jaxrs:serviceBeans>
>      <jaxrs:providers>
>          <ref  component-id="authenticationFilter"  />
>      </jaxrs:providers>
> </jaxrs:server>
>
> When I execute the REST service, I try to get the Subject in the code 
> as below but it is always null:
>
> AccessControlContext  acc=  AccessController.getContext();
> if  (acc==  null) {
>    throw  new  RuntimeException("access control context is null");
> }
>
> Subject  subject=  Subject.getSubject(acc);
> if  (subject==  null) {
>    throw  new  RuntimeException("subject is null");
> }
>
> Interestingly if I inject the javax.ws.rs.core.SecurityContext into 
> the CXF REST service, I do get a security principal.
>
> public  Response  echo(@Context  SecurityContext  context) {
>     Principal  user=  context.getUserPrincipal();
> }
>
> Is there another configuration required in Karaf or is this a bug in 
> either Karaf or CXF? Would love to hear if anyone else came across this.
>
> Cheers, Niels
>
> BTW: I tried the same in karaf 2.3.9, 2.4.1 and 3.0.2 with exact same 
> result.
>


-- 
  
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
Talend Application Integration Division http://www.talend.com