WebService Method Authorization
fambad Feb 9, 2016 1:25 AMHi,
I have a POJO based webservice and want to use the annotation @RolesAllowed to authorize specific roles to access the web service methods.
My Web Service looks like this:
@Stateless
@WebService(
endpointInterface = "marabu.pegasos.server.ihe.xds_b.infoset._2007.DocumentRegistryPortType",
wsdlLocation = "META-INF/wsdl/XDS.b_DocumentRegistry.wsdl",
serviceName = "DocumentRegistry_Service",
targetNamespace = "urn:ihe:iti:xds-b:2007",
portName = "DocumentRegistry_Port_Soap12")
@EndpointConfig(
configFile = "/META-INF/security-jaxws-endpoint-config.xml",
configName = "XDS WSSecurity Endpoint")
@WebContext(
contextRoot = XDSConstants.URL_PART__CONTEXT_ROOT,
urlPattern = XDSConstants.URL_PART__SERVLET_PATH_REGISTRY_TF7,
secureWSDLAccess = false,
transportGuarantee = "NONE" // "INTEGRAL" or "CONFIDENTIAL" or "NONE"
)
@BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING)
@Addressing(enabled = true, required = true)
@HandlerChain(file = "/META-INF/XDSRegistry-HandlerChain.xml")
@SecurityDomain(value = XDSConstants.SECURITY_DOMAIN)
public class DocumentRegistryService implements DocumentRegistryPortType {
@Override
@RolesAllowed({XDS_ROLE__REGISTER_DOCUMENTSETB, XDS_ROLE__PERMIT_ALL, ROLEKEY_PERMIT_ALL})
public RegistryResponseType documentRegistryRegisterDocumentSetB(SubmitObjectsRequest body) {
...
}
}
My security endpoint configuration "XDS WSSecurity Endpoint" looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<jaxws-config xmlns="urn:jboss:jbossws-jaxws-config:4.0" xmlns:javaee="http://java.sun.com/xml/ns/javaee">
<endpoint-config>
<config-name>XDS WSSecurity Endpoint</config-name>
<pre-handler-chains>
<javaee:handler-chain>
<javaee:protocol-bindings>##SOAP11_HTTP ##SOAP12_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP_MTOM</javaee:protocol-bindings>
<!--javaee:handler>
<javaee:handler-name>WSAuthorizationHandler</javaee:handler-name>
<javaee:handler-class>org.picketlink.trust.jbossws.handler.WSAuthorizationHandler</javaee:handler-class>
</javaee:handler-->
<javaee:handler>
<javaee:handler-name>WSAuthenticationHandler</javaee:handler-name>
<javaee:handler-class>org.picketlink.trust.jbossws.handler.WSAuthenticationHandler</javaee:handler-class>
</javaee:handler>
<javaee:handler>
<javaee:handler-name>SAML2Handler</javaee:handler-name>
<javaee:handler-class>org.picketlink.trust.jbossws.handler.SAML2Handler</javaee:handler-class>
</javaee:handler>
<javaee:handler>
<javaee:handler-name>Recording Handler</javaee:handler-name>
<javaee:handler-class>org.jboss.ws.common.invocation.RecordingServerHandler</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</pre-handler-chains>
</endpoint-config>
</jaxws-config>
I use picketlink to extract the SAML Assertion from the soap message and authenticate the user via the WSAuthenticationHandler. I cannot use the WSAuthorizationHandler because it searches for the jboss-wsse.xml within the WEB-INF folder. But I deploy it as JAR not as WAR. So there is no WEB-INF folder.
So I want to define the method permissions using the @RolesAllowed annotation like I did before in JBoss AS 6.
But it don't work in Wildfly 10. The method access is checked before the execution of the handler chain. So I get follow error:
06:29:16,286 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (default task-110) Interceptor for {urn:ihe:iti:xds-b:2007}DocumentRegistry_Service#{urn:ihe:iti:xds-b:2007}DocumentRegistry_RegistryStoredQuery has thrown exception, unwinding now: ja
va.lang.SecurityException: JBWS024094: Authorization failed, principal=null
at org.jboss.wsf.stack.cxf.interceptor.HandlerAuthInterceptor$JBossWSHandlerChainInvoker.checkAuthorization(HandlerAuthInterceptor.java:172)
at org.jboss.wsf.stack.cxf.interceptor.HandlerAuthInterceptor$JBossWSHandlerChainInvoker.invokeProtocolHandlers(HandlerAuthInterceptor.java:112)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessageInternal(SOAPHandlerInterceptor.java:169)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:124)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:71)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)
at org.jboss.wsf.stack.cxf.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:108)
at org.jboss.wsf.stack.cxf.transport.ServletHelper.callRequestHandler(ServletHelper.java:134)
at org.jboss.wsf.stack.cxf.CXFServletExt.invoke(CXFServletExt.java:88)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:212)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.jboss.wsf.stack.cxf.CXFServletExt.service(CXFServletExt.java:136)
at org.jboss.wsf.spi.deployment.WSFServlet.service(WSFServlet.java:140)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
For current developement purposes I removed the @RolesAllowed annotation. But I got the same error. Now I have to set @PermitAll to each method so that I'm allowed to access it.
So what is the correct way to set the method permission now? Certainly I could define an own authorization handler which set the permissions directly but I think there should be a more sophisticated way? And using such a handler won't prevent the need of the @PermitAll annotation to survive the first permission check.
Kind regards,
Marco