Web服务soap标头身份验证

时间:2010-06-08 14:54:28

标签: web-services soap header

我有一个Web服务,我想从soap标头验证用户。也就是说,我想检查soap标头中的令牌ID(随机数)并根据我的数据库中的值验证它,如果数字匹配,我允许请求通过,否则我不想允许执行我的Web方法。

使用SOAP标头是否有任何干净的方法?

谢谢,

Mrinal Jaiswal

2 个答案:

答案 0 :(得分:4)

你有没有看过WS-Security?假设您尚未将其用于其他内容,则可以在Username元素中携带令牌等。

<?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>

答案 1 :(得分:1)

我使用JDK API创建了一个Web服务,并通过soap标头进行简单的身份验证。 这个简单的项目提供了两种服务:

  • 登录
  • 从服务器获取消息

客户端将soap body中的用户名和密码发布到服务器,如果登录成功,服务器将在soap标头中返回一个令牌。 客户端通过在soap头中包含此令牌来调用getMessage服务,服务器检查令牌(如果它是登录用户),然后返回成功消息,否则返回失败的消息。

以下是代码:

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();
    }

}