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/beans.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.

Reply via email to