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
<ch...@die-schneider.net <mailto:ch...@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