Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web service soap header authentication

I have a web service, i want to authenticate the user from the soap header. That is, i want to check a token id (random number) in soap header and validate it against a value in my database and if the number matches i allow the request to go through otherwise i dont want to allow execution of my web method.

Is there any clean way of doing it using SOAP headers?

Thanks,

Mrinal Jaiswal

like image 335
mickey mouse Avatar asked Aug 25 '26 00:08

mickey mouse


2 Answers

Have you looked into WS-Security? Assuming you're not already using it for something else, you could carry your token in the Username element, etc.

<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
        <wsse:Username>yourusername</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">yourpassword</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body>
    <yourbodygoeshere>
  </soapenv:Body>
</soapenv:Envelope>
like image 136
Justin Garrick Avatar answered Aug 26 '26 12:08

Justin Garrick


I created a web service using JDK API, and do a simple authentication by soap header. This simple project provide two services:

  • login
  • get message from server

Client posts username and password in the soap body to server, if login successfully, the server will return a token in the soap header. Clients calls getMessage service by including this token in the soap header, server check the token, if it is a logged in user, then return a success message, otherwise return a failed message.

The following is the code:

package com.aug.ws;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.Holder;

//Service Endpoint Interface
@WebService
@SOAPBinding(style = Style.RPC)
public interface HelloWorld {

    @WebMethod
    void login(String userName, String password, @WebParam(header = true, mode = Mode.OUT, name = "token") Holder<String> token);

    String getMessage(String message);
}


package com.aug.ws;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebParam.Mode;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;

import com.sun.xml.internal.ws.api.message.Header;
import com.sun.xml.internal.ws.api.message.HeaderList;
import com.sun.xml.internal.ws.developer.JAXWSProperties;

@WebService(endpointInterface = "com.aug.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld {

    private Map<String, String> authorizedUsers = new HashMap<String, String>();

    @Resource
    WebServiceContext wsctx;

    @Override
    @WebMethod
    public void login(String userName, String password, @WebParam(header = true, mode = Mode.OUT, name = "token") Holder<String> token) {
        if (("user1".equals(userName) && "pwd1".equals(password)) || ("user2".equals(userName) && "pwd2".equals(password))) {
            String tokenValue = "authorizeduser1234" + userName;
            token.value = tokenValue;
            authorizedUsers.put(tokenValue, userName);

            System.out.println("---------------- token: " + tokenValue);
        }
    }

    @Override
    @WebMethod
    public String getMessage(String message) {
        if (isLoggedInUser()) {
            return "JAX-WS message: " + message;
        }
    return "Invalid access!";
    }

    /**
     * Check token from SOAP Header
     * @return
     */
    private boolean isLoggedInUser() {
        System.out.println("wsctx: " + wsctx);

        MessageContext mctx = wsctx.getMessageContext();
        HeaderList headerList = (HeaderList)     mctx.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);

        String nameSpace = "http://ws.aug.com/";
        QName token = new QName(nameSpace, "token");

        try {
            Header tokenHeader = headerList.get(token, true);
            if (tokenHeader != null) {
                String user = authorizedUsers.get(tokenHeader.getStringContent());
                if (user != null) {
                    System.out.println(user + " has logged in.");
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
}


package com.aug.endpoint;
import javax.xml.ws.Endpoint;

import com.aug.ws.HelloWorldImpl;

public class HelloWorldPublisher {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Endpoint.publish("http://localhost:9000/ws/hello", new HelloWorldImpl());

        System.out.println("\nWeb service published @ http://localhost:9000/ws/hello");
        System.out.println("You may call the web service now");
    }

}


package com.aug.client;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.aug.ws.HelloWorld;
import com.sun.xml.internal.ws.api.message.HeaderList;
import com.sun.xml.internal.ws.api.message.Headers;
import com.sun.xml.internal.ws.developer.JAXWSProperties;
import com.sun.xml.internal.ws.developer.WSBindingProvider;

public class HelloWorldClient {

    private static final String WS_URL = "http://localhost:9000/ws/hello?wsdl";
    private static final String NAME_SPACE = "http://ws.aug.com/";

    public static String login() throws Exception {

        URL url = new URL(WS_URL);
        QName qname = new QName(NAME_SPACE, "HelloWorldImplService");

        Service service = Service.create(url, qname);
        HelloWorld hello = service.getPort(HelloWorld.class);

        hello.login("user1", "pwd1", null);

        WSBindingProvider bp = (WSBindingProvider) hello;
        HeaderList headerList = (HeaderList)     bp.getResponseContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
        bp.close();

        return headerList.get(new QName(NAME_SPACE, "token"), true).getStringContent();
    }

    public static void getMessage() throws Exception  {
        String token = login();
        System.out.println("token: " + token);

        URL url = new URL(WS_URL);
        QName qname = new QName(NAME_SPACE, "HelloWorldImplService");

        Service service = Service.create(url, qname);
        HelloWorld hello = service.getPort(HelloWorld.class);
        WSBindingProvider bp = (WSBindingProvider) hello;

        bp.setOutboundHeaders(
                Headers.create(new QName(NAME_SPACE, "token"), token)
        );

        System.out.println(hello.getMessage("hello world"));

        bp.close();
    }

    public static void main(String[] args) throws Exception {
        getMessage();
    }

}
like image 21
dereck Avatar answered Aug 26 '26 12:08

dereck



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!