All/most the CXF components have .spring packages which contain the Spring
related code, so starting with a 'provided' dependency
seems like a natural step in bringing in spring-security related contributions.
Perhaps just in common/common, if it will be
reusable
by both JAXRs & JAXWS/WS-Security. Or adding them to modules as appropriate.
Perhaps the JAXRS component will have some
SpringSecurity handler capable of processing individual URIs.
With a 'provided' dependency we will just add optional OSGI imports to
cxf-jaxrs, cxf-minimal and cxf-all bundles and OSGi users
will install Spring Security bundles if needed.
Having a seperate Maven module seems like a neat idea but I'm not sure how
reusable will this module be across multiple components ?
For ex, is it likely that for say a CXF JAX-RS bundle t will end up downloading
the dependencies it does not need (if say this
module ships something that would make sense only in a WS-Security case) ?
Another concern is DOSGi - DOSGi just depends on a cxf-minimal bundle. So for
this module be picked up we'll have to bundle it in.
This will lead to a strong Import_Package dependency and we will have to do the
same optional imports in cxf bundles to relax it...
I'm kind of preferring having a provided dependency at the moment as I'm not
sure yet what effect having a sep SpringSec module will
have.
Thoughts ? Andreas - what do you you think about starting with a 'provided'
dependency ? We can still have a separate module later
on once we see how common or per-module specific Spring-Security contributions
are working ?
I'm also +1 on having CXF better integrated with SpringSecurity. The only
question for me is how to make it in the least intrusive
way initially...
cheers, Sergey
On Mon September 21 2009 5:52:32 am Andreas Veithen wrote:
Actually, I was going to propose to create a new Maven module that
contains all Spring Security related code. If we do it like that, then
there is no issue with the dependency on Spring Security.
Either way is fine by me. :-) I really have no problem shipping spring
security as well if it's needed, especially if we get a couple good samples
that show it all working.... (hint hint hint... ;-) ) This definitely
fills some gaps in the security related implementations and such. If we can
get stuff that shows full spring security integration, that's huge.
Dan
Andreas
On Mon, Sep 21, 2009 at 11:40, Sergey Beryozkin <[email protected]>
wrote:
> Hi
>
> It is brilliant, thanks. it would be nice to have this feature and a
> WSS4J spring security aware password callback handler contributed to CXF
> but the issue is we don't actually ship SpringSecurity...
> Dan - would it make sense to introduce a 'provided' dependency on the
> Spring security (core) modules ? And then modules like ws-security or
> jaxrs can have contributions in ....spring.security packages ?
> Alternatively we can have this feature and handler demonstrated perhaps
> in the system tests area, with the contributions from Andreas being
> acknowledged ?
>
> cheers, Sergey
>
> ----- Original Message ----- From: "Andreas Veithen"
> <[email protected]>
> To: <[email protected]>
> Sent: Sunday, September 20, 2009 10:16 PM
> Subject: Re: CXF + JAX-RS + Spring Security (Acegi) for authorization
>
>
> I improved this a bit further by creating a feature that adds the invoker
> proxy:
>
> public class AuthorizationFeature extends AbstractFeature {
> @Override
> public void initialize(Server server, Bus bus) {
> Service service = server.getEndpoint().getService();
> service.setInvoker(new
> SpringSecurityInvokerProxy(service.getInvoker()));
> }
> }
>
> Now the configuration looks like this:
>
> <jaxrs:server address="/rest">
> <jaxrs:serviceBeans>
> ...
> </jaxrs:serviceBeans>
> <jaxrs:providers>
> ...
> </jaxrs:providers>
> <jaxrs:features>
> <bean class="myapp.security.AuthorizationFeature"/>
> </jaxrs:features>
> </jaxrs:server>
>
> The advantage is that it works in exactly the same way for all
> frontends (I tested this successfully with JAX-RS and the simple
> frontend) and that there is no need to figure out how to set up the
> target invoker.
>
> Does the code in AuthorizationFeature look good?
>
>
> I also have a working integration between WSS4J and Spring Security
> which plays nicely with
> SpringSecurityInvokerProxy/AuthorizationFeature. Here is the
> configuration for a simple scenario:
>
> <security:authentication-provider>
> <security:user-service>
> <security:user name="joe" password="password"
> authorities="ROLE_USER,ROLE_ADMIN"/>
> <security:user name="bob" password="password"
> authorities="ROLE_USER"/> </security:user-service>
> </security:authentication-provider>
>
> <simple:server serviceClass="myapp.MyService" address="/myservice">
> <simple:serviceBean>
> <bean class="myapp.MyServiceImpl"/>
> </simple:serviceBean>
> <simple:inInterceptors>
> <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
> <constructor-arg>
> <map>
> <entry key="action" value="UsernameToken"/>
> <entry key="passwordType" value="PasswordText"/>
> <entry key="passwordCallbackRef">
> <ssec:server-password-callback-handler
> logExceptions="true" nestExceptions="false"/>
> </entry>
> </map>
> </constructor-arg>
> </bean>
> </simple:inInterceptors>
> </simple:server>
>
> ssec:server-password-callback-handler is a Spring handler that creates
> a password callback handler that delegates authentication to Spring
> Security.
>
> If there is interest, I can contribute the corresponding code.
>
> Andreas
>
>
> On Wed, Sep 16, 2009 at 10:54, Sergey Beryozkin
>
> <[email protected]> wrote:
>> Hi Andreas
>>
>> This does look like a neat solution. I think it's worth documenting what
>> you
>> suggested.
>> Note that we don't support in-only operations for JAX-RS (just yet), but
>> either way, what you've done seems to cover all the variations. In one
>> of the system tests I added a custom invoker which extends JAXRSInvoker
>> but your approach works well too and is more generic.
>>
>>> - The service is not necessarily invoked in the same thread as the
>>> interceptor
>>
>> I thought that interceptors and the service were actually invoked on the
>> same thread. It is transport threads like Jetty threads won't
>> necessarily end up invoking on the service.
>>
>> Dan, can it be that a thread which invoked a given interceptor won't
>> invoke
>> the service endpoint ?
>>
>> By the way there's also a similar test showing how the spring security
>> can be used without using annotations :
>>
>>
>> systest/jaxrs/src/test/resources/jaxrs_security_no_annotations/WEB-INF/b
>>eans.xml
>>
>> cheers, Sergey
>>
>> Andreas Veithen-2 wrote:
>>> I'm currently trying to integrate JAX-RS with Spring Security for
>>> authorization (authorization only; I use a custom authentication
>>> mechanism). I found the following resources describing integration
>>> between CXF and Spring Security:
>>>
>>> -
>>>
>>> http://www.nabble.com/Re:-CXF%2BACEGI-%2B-Anybody-out-there--p12759358.
>>>html (WS-Security)
>>> - http://www.emforge.org/wiki/WebServicesImplementation (WS-Security)
>>> - There is also a JAX-RS systest (see
>>> systest/jaxrs/src/test/resources/jaxrs_security/WEB-INF/beans.xml in
>>> the trunk) that integrates Spring Security with JAX-RS.
>>>
>>> In order for (annotation driven) authorization to work, it is
>>> necessary to use SecurityContextHolder to associate the
>>> SecurityContext/Authentication with the current thread. In the first
>>> two references, this is done in a custom interceptor, while the
>>> systest uses a servlet filter (that implements HTTP basic
>>> authentication). I see two issues with these approaches:
>>> - The service is not necessarily invoked in the same thread as the
>>> interceptor or servlet filter (e.g. in-only operations). If that
>>> happens, the security context will not be set up correctly.
>>> - The code in the first two references never resets the authentication
>>> in the SecurityContext (by calling
>>> SecurityContextHolder.getContext().setAuthentication(null)). I fear
>>> that it is therefore possible that a service may accidentally get the
>>> authentication from a previous request. This is only a problem when
>>> using an interceptor, but using a servlet filter may not always be
>>> possible (e.g. for WS-Security).
>>>
>>> The approach that I use to avoid these problems is to insert a proxy
>>> in front of the Invoker (JAXRSInvoker in my case). This proxy looks as
>>> follows:
>>>
>>> public class SpringSecurityInvokerProxy implements Invoker {
>>> private Invoker target;
>>>
>>> public Invoker getTarget() { return target; }
>>> public void setTarget(Invoker target) { this.target = target; }
>>>
>>> public Object invoke(Exchange exchange, Object o) {
>>> Authentication authentication = exchange.get(Authentication.class);
>>> SecurityContext securityContext =
>>> SecurityContextHolder.getContext();
>>> securityContext.setAuthentication(authentication);
>>> try {
>>> return target.invoke(exchange, o);
>>> } finally {
>>> securityContext.setAuthentication(null);
>>> }
>>> }
>>> }
>>>
>>> The Authentication object is added to the exchange by an interceptor
>>> that implements the custom authentication mechanism. The try/finally
>>> block here makes sure that the security context is reset right after
>>> the invocation of the service. The corresponding configuration is:
>>>
>>> <jaxrs:server address="/rest">
>>> <jaxrs:serviceBeans>
>>> ...
>>> </jaxrs:serviceBeans>
>>> <jaxrs:providers>
>>> ...
>>> </jaxrs:providers>
>>> <jaxrs:invoker>
>>> <bean class="myapp.security.SpringSecurityInvokerProxy">
>>> <property name="target">
>>> <bean class="org.apache.cxf.jaxrs.JAXRSInvoker"/>
>>> </property>
>>> </bean>
>>> </jaxrs:invoker>
>>> </jaxrs:server>
>>>
>>> This works well for me, but I would like to know if there is a
>>> better/easier way to achieve this.
>>>
>>> Regards,
>>>
>>> Andreas
>>
>> --
>> View this message in context:
>> http://www.nabble.com/CXF-%2B-JAX-RS-%2B-Spring-Security-%28Acegi%29-for
>>-authorization-tp25462665p25468445.html Sent from the cxf-user mailing
>> list archive at Nabble.com.
--
Daniel Kulp
[email protected]
http://www.dankulp.com/blog