【问题标题】:Secure a java embedded web service with javax.jws without application server在没有应用程序服务器的情况下使用 javax.jws 保护 java 嵌入式 Web 服务
【发布时间】:2011-09-15 10:31:31
【问题描述】:

我编写了以下代码来实现一个 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();

我得到一个空指针异常...有什么想法吗?

【问题讨论】:

  • 如果这真的在 localhost 上运行,我会(硬编码)服务器只接受来自 localhost 的连接和/或将网络配置为不允许世界其他地方与此端口通信。
  • 我不能这样做,因为架构不取决于我,而且这两个应用程序可能有一天会以最快的方式重新定位

标签: java service web


【解决方案1】:

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

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

这里链中的处理程序会将标头添加到传出请求。仅为传出消息配置此项。

【讨论】:

    【解决方案2】:

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

    您还有 2 个选择。

    1. 在 SOAP 级别进行身份验证。我不会真的推荐 它。但如果您这样做,请注意 Endpoint 不会部署 WSDL。因此,您必须与正在连接的客户端进行准确通信, 您期望的 SOAP 标头。可以通过以下方式编写WSDL 您自己并将其“附加”到Endpoint
    2. 在 http 请求级别进行身份验证。 IE。添加令牌或 cookie 到 http 请求。老实说,我不记得这是否 使用Endpoint 很容易

    【讨论】:

      猜你喜欢
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多