User authentication in SOAP Webservices

lpinto.eu picture lpinto.eu · Oct 14, 2011 · Viewed 10.8k times · Source

I made a question about JAX-WS, Authentication and Authorization - How to?; there was a discussion about security levels, and where to store user credentials.

Now after some conclusions, I want to try one of those scenarios:

  • SOAP web services - metro
  • Message level security - Mutual certificate authentication, to authenticate the client application
  • User credential in the Soap Header

How to get the credentials and do the authorization? I have 2 ideas:

  • JAAS (I don't know anything about this);
  • SOAP handler - using the WebServiceContext to extract the credentials from the message and do the authorization "by hand".

Can you help me to decide the best way, and how to implement it?

Remember that I want mutual certificate, plus a user token.

Answer

dma_k picture dma_k · Oct 21, 2011

JAAS does not define how the authentication information should look like in SOAP, but WS-Security defines what kind of standardized tokens you can use during client-server exchange (Username+password token / X.509 certificate / SAML token / Kerberos Token).

EDIT: With respect to Metro WebService stack, you need (steps taken from here and here):

  • Inject the handler, that implements javax.xml.ws.handler.soap.SOAPHandler to JAX-WS handler chain either programmatically via ((BindingProvider)port).getBinding().setHandlerChain(Collections.singletonList(handler)) or declaratively by adding @HandlerChain(file = "handlers.xml") annotation to your WS endpoint interface.
  • The handler should create XWSSProcessor instance using XWSSProcessorFactory, which is passed the callback handler that implements javax.security.auth.callback.CallbackHandler.
  • The callback handler e.g. defines a validator on callback (depends on callback type).

This is the same as "doing by hand" (as the 1st step is to intersect the SOAP message anyway), with some WSS sugar on top. But WSIT (and CXF) use JAAS API and they provide standard implementations for various authentication tokens. Enabling them needs some configuration / coding efforts, but the benefit is that if you later decide to switch from plainttext to Kerberos authentication, you don't need to code a lot. Also "doing by hand" means that you need to deal with authentication information on XML level and what you'll do is implementing one of the standards.

I suggest using Apache CXF that bases on WSS4J – the WS-Security implementation from Apache. You can easily find tutorials (e.g. here and here for Username+password, here and here for SAML) that show to define callback / interceptors to verify authentication information. The advantage of CXF is that it has nice integration with Spring.