使用 javax.jws 保护 Java 嵌入式 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();

我收到空指针异常...有什么想法吗?

我做了一个工作程序。只是为了补充你已经发现的内容,以下是使用处理程序的一种方法

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

在这里,链中的处理程序将向传出请求添加标头。仅为传出邮件配置此项。

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

您还有 2 个选择。

  1. 在 SOAP 级别执行身份验证。我真的不推荐它。但是,如果这样做,请注意,Endpoint不会部署 WSDL . 因此,您必须与连接的客户端进行精确通信,所需的SOAP标头。虽然可以写一个WSDL自己并将其"附加"到Endpoint.
  2. 在 http 请求级别执行身份验证。 即添加令牌或cookie 到 http 请求。老实说,我不记得这是否使用Endpoint很容易

相关内容

最新更新