Search code examples
soapejbcdideltaspikepicketlink

PicketLink / Deltaspike security does not work in SOAP (JAX-WS) layer (CDI vs EJB?)


I am long time Spring user, now had to switch to Java EE only. There are many things that just don't work as expected...

I have a CXF / SOAP service

@WebService( ... )
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface KlassePortType { ... 

    @WebMethod(...)
    @WebResult(...)
    public ListOutputType list(@WebParam(...)
            ListInputType request
        );
    ...
    }

an implementation:

@WebService(...)
public class KlasseImpl  implements KlassePortType { ...

    @Inject
    private KlasseService klasseService;

    @DeclaresRole
    @Override
    public ListOutputType list(ListInputType request) {
        return klasseService.list(request);
    }
}

and also a KlasseService which is a Stateless EJB:

@Stateless
public class KlasseService { ...

    @DeclaresRole
    public ListOutputType list(ListInputType listInputType) {
        METHOD LOGIC
    }
... 
}

The DeclaresRole annotation is specified as:

@Retention(value = RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@SecurityBindingType
public @interface DeclaresRole {
}

And has matching DeltaSpike authorizer:

@ApplicationScoped
public class CustomAuthorizer {...
    @Secures
    @DeclaresRole
    public boolean doSecuredCheck() throws Exception
    {
        SECURITY CHECK LOGIC
    }
...
}

my beans.xml looks folllowing:

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                           http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
    <interceptors>
        <class>org.apache.deltaspike.security.impl.extension.SecurityInterceptor</class>
    </interceptors>
</beans>

The CutomAuthorizer code is never being called, when SOAP request is being handled, (put annotation on interface, implementation and even service - EJB). However, when the same annotation is being used for methods invoked from ie. JSF - everything works as expected.

I found some related question: Deltaspike and @Stateless Bean However reading this: Where to use EJB 3.1 and CDI? makes me think the EJB container should be aware of CDI interceptors etc. Also other, custom interceptors (@AroundInvoke) work for me, and the JSF reqests are being secured, as expected.

Am I missing something obvious, that will make PicketLink/Deltaspike usable in SOAP layer? As a alternative I may go with Spring Security + AspectJ pointcuts, as documented: http://forum.spring.io/forum/spring-projects/security/119811-method-security-java-ee-cdi but that just sounds like a lot of hassle....

PS. I am using WildFly 8.2 (on WF9 - same results)


Solution

  • I sorted it out. beans.xml with DeltaSpike SecurityInterceptor must be present in the same module in which the annotation is being used. In my setup it was only in module that delivers security code. Also it only works on any EJB or CDI bean, except for @WebService (here CXF on WF8/9) - as suggested by @JohnAment I assume that SOAP endpoints are not automatically registered in EJB/CDI context, thus cannot be secured directly by this annotation.

    Adding @Stateless to alredy present @WebService prevents application from being deployed:

    JBAS017312: KlasseImpl has the wrong component type, it cannot be used as a web component
    

    I believe anyway, that business logic should be separated from the SOAP (or any other) endpoint, thus I successfully use the annotation on injected into SOAP business service.