使用javax.jws保护java嵌入式Web服务,而无需应用程序服务器

时间:2011-09-15 10:31:32

标签: java service web

我编写了以下代码来实现一个Java Web服务,该服务与在同一主机上用另一种语言编写的应用程序进行通信:

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService(name = "MyWebService") 
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) 
public class MyWebService { 

    @WebMethod(operationName = "methodName", action = "urn:#methodName") 
    @WebResult(name = "result",  partName = "output") 
    public String methodName(@WebParam(name = "param1",  partName = "input")  String param1,
                                        @WebParam(name = "param2",  partName = "input")  String param2){

            // ...do something

        return "You called this service with params: "  + param1 + "," + param2;
    }

由于要求不使用应用程序服务器公开Web服务,因此我从另一个类实例化服务,如下所示:

        Endpoint endpoint = Endpoint.create(new MyWebService());
        URL url = new URL("http://localhost:7777/MyWebService");
        endpoint.publish(url.toString());

问题:

1)考虑到该项目的架构,使用用户名和密码保护此服务的最简单方法是什么? 任何代码示例将不胜感激。

2)我做了一些研究,发现使用SOAPHandler,我认为它对我有用。 在使用SOAPHandler类的情况下,如何向邮件添加标头以要求客户端进行身份验证?

提前谢谢


非常感谢我所遵循的反应,但

当我检查任何标题时,例如:

SOAPHeader header = soapContext.getMessage().getSOAPPart().getEnvelope().getHeader();
Iterator<SOAPElement> iterator = header.getAllAttributes();

我得到一个nullpointer异常......任何想法?

2 个答案:

答案 0 :(得分:0)

我做了一个工作计划。只是添加到您已经发现的内容,以下是使用处理程序

的方法
Endpoint endpoint = Endpoint.create(new MyWebService());
        Binding binding = endpoint.getBinding();
        List<Handler> handlerChain = new ArrayList<Handler>(1);
        handlerChain.add(new MyHandler());
        binding.setHandlerChain(handlerChain);
        URL url = new URL("http://localhost:7777/MyWebService");
        endpoint.publish(url.toString());

MyHandler是扩展Handler接口的类。或者,您可以使用@HandlerChain注释,该注释需要一个xml配置文件用于处理程序。为传入消息

配置此项
public class MyHandler implements SOAPHandler{

    @Override
    public Set<?> getHeaders() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void close(MessageContext context) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean handleFault(MessageContext context) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean handleMessage(MessageContext context) {
        System.out.println("Hehehe the handler");

        SOAPMessageContext soapContext = (SOAPMessageContext)context;
        try {
            SOAPHeader header = soapContext.getMessage().getSOAPPart().getEnvelope().getHeader();
            //Check there if the required data (username/password) is present in header or not and return true/false accordingly. 
        } catch (SOAPException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

}

从客户端来看,如果您的客户端使用JAB-WS,则必须使用客户端处理程序。以下是典型的JAX-WS客户端调用示例

Dispatch<Source> dispatch = … create a Dispatch<Source>
dispatch.getBinding().setHandlerChain(chain)
Source request = … create a Source object
Source response = dispatch.invoke(request);

此处链中的处理程序将向传出请求添加标头。仅针对传出消息进行配置。

答案 1 :(得分:0)

你做的很公平。
关于身份验证,您只需公开一种将用户名和密码作为登录凭据传递的方法 一旦用户提供了正确的凭证,用户就已经过身份验证 注意:现在您必须维护会话数据,并确保传入的请求来自经过身份验证的用户。 Endpoint仅在内部部署轻量级http服务器。您必须设计Web服务实现以在请求之间保持“状态”。

您还有2个选项。

  1. 在SOAP级别进行身份验证。我不会真的推荐 它。但是如果你这样做,请注意Endpoint没有部署 WSDL。所以你必须准确地与客户连接, 您期望的SOAP标题。虽然可以写一个WSDL 自己并将其“附加”到Endpoint
  2. 在http请求级别执行身份验证。即添加令牌或 cookie的http请求。说实话,我不记得是否这样 使用Endpoint
  3. 很容易