【问题标题】:JAX-WS and BASIC authentication, when user names and passwords are in a databaseJAX-WS 和 BASIC 身份验证,当用户名和密码在数据库中时
【发布时间】:2023-03-15 22:36:01
【问题描述】:

我是 JAX-WS 的新手,有一点我不明白。

有很多关于如何设置 JAX-WS 安全性的教程,但在几乎所有情况下 BindingProvider.USERNAME_PROPERTY 和 BindingProvider.PASSWORD_PROPERTY 都存储在一些 .xml 文件中(取决于我相信的容器)——它们是“硬编码”就是这样。这就是我不明白的。如何通过将 BindingProvider.USERNAME_PROPERTY 和 BindingProvider.PASSWORD_PROPERTY 与数据库中的用户名和密码进行比较来验证 Web 服务客户端?我尝试在客户端设置 BindingProvider.USERNAME_PROPERTY 和 BindingProvider.PASSWORD_PROPERTY,如下所示:

    ShopingCartService scs = new ShopingCartService(wsdlURL, name);
    ShopingCart sc = scs.getShopingCartPort();
    Map<String, Object> requestContext = ((BindingProvider)sc).getRequestContext();
    requestContext.put(BindingProvider.USERNAME_PROPERTY, userName);
    requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
    sc.someFunctionCall();

然后,在服务器端这样检索:

@Resource
WebServiceContext wsContext;

@WebMethod
public void someFunctionCall() {
    MessageContext mc = wsContext.getMessageContext();
    mc.get(BindingProvider.USERNAME_PROPERTY);
    mc.get(BindingProvider.PASSWORD_PROPERTY);
}

但我总是得到空值,我没有在 xml 中设置任何东西,Web 服务工作得很好,除了我无法获取这些变量:(

我同时在 java 1.6、tomcat 6 和 JAX-WS 上运行。

非常感谢任何有关使用数据库密码验证用户身份的帮助, 谢谢。

【问题讨论】:

  • 我也尝试在 SOAPHandler 中检查 BindingProvider.USERNAME_PROPERTY,仍然为空。

标签: java jax-ws tomcat6 basic-authentication


【解决方案1】:

如果您以这种方式将客户端的用户名和密码放入请求中:

URL url = new URL("http://localhost:8080/myapplication?wsdl");
MyWebService webservice = new MyWebServiceImplService(url).getMyWebServiceImplPort();
Map<String, Object> requestContext = ((BindingProvider) webservice).getRequestContext();
requestContext.put(BindingProvider.USERNAME_PROPERTY, "myusername");
requestContext.put(BindingProvider.PASSWORD_PROPERTY, "mypassword");

并调用您的网络服务

String response = webservice.someMethodAtMyWebservice("test");

然后您可以在服务器端读取这样的基本身份验证字符串(您必须添加一些检查并进行一些异常处理):

@Resource
WebServiceContext webserviceContext;

public void someMethodAtMyWebservice(String parameter) {
    MessageContext messageContext = webserviceContext.getMessageContext();
    Map<String, ?> httpRequestHeaders = (Map<String, ?>) messageContext.get(MessageContext.HTTP_REQUEST_HEADERS);
    List<?> authorizationList = (List<?>) httpRequestHeaders.get("Authorization");
    if (authorizationList != null && !authorizationList.isEmpty()) {
        String basicString = (String) authorizationList.get(0);
        String encodedBasicString = basicString.substring("Basic ".length());
        String decoded = new String(Base64.getDecoder().decode(encodedBasicString), StandardCharsets.UTF_8);
        String[] splitter = decoded.split(":");
        String usernameFromBasicAuth = splitter[0];
        String passwordFromBasicAuth = splitter[1];
    }

【讨论】:

    【解决方案2】:

    在您的客户端 SOAP 处理程序中,您需要如下设置 javax.xml.ws.security.auth.username 和 javax.xml.ws.security.auth.password 属性:

    public class ClientHandler implements SOAPHandler<SOAPMessageContext>{
    
        public boolean handleMessage(final SOAPMessageContext soapMessageContext)
        {
            final Boolean outInd = (Boolean)soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
            if (outInd.booleanValue())
            {
              try 
              {
                   soapMessageContext.put("javax.xml.ws.security.auth.username", <ClientUserName>);
                   soapMessageContext.put("javax.xml.ws.security.auth.password", <ClientPassword>);
              } 
              catch (Exception e)
              {
                   e.printStackTrace();
                   return false;
              }
             }
          return true;
         }
    }
    

    【讨论】:

      【解决方案3】:

      我认为您正在寻找应用程序级别的 JAX-WS 身份验证,而不是服务器级别的 HTTP basic。请参阅以下完整示例:

      Application Authentication with JAX-WS

      在 Web 服务客户端站点上,只需将您的“用户名”和“密码”放入请求标头中即可。

      Map<String, Object> req_ctx = ((BindingProvider)port).getRequestContext();
      req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WS_URL);
      
      Map<String, List<String>> headers = new HashMap<String, List<String>>();
      headers.put("Username", Collections.singletonList("someUser"));
      headers.put("Password", Collections.singletonList("somePass"));
      req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
      

      在Web服务服务器站点,通过WebServiceContext获取请求头参数。

      @Resource
      WebServiceContext wsctx;
      
      @WebMethod
      public String method() {
          MessageContext mctx = wsctx.getMessageContext();
      
          Map http_headers = (Map) mctx.get(MessageContext.HTTP_REQUEST_HEADERS);
          List userList = (List) http_headers.get("Username");
          List passList = (List) http_headers.get("Password");
          //...
      

      【讨论】:

      • 请问您是从哪里获得这些信息的?我需要官方信息来源,但我找不到任何有足够信息的官方来源!
      【解决方案4】:

      我遇到了类似的情况,我需要向我的 WS 提供:用户名、密码和 WSS 密码类型。

      我最初使用“Http Basic Auth”(作为@ahoge),我尝试使用@Philipp-Dev 的参考。也。我没有得到成功的解决方案。

      在谷歌稍微深入搜索后,我找到了这篇文章:

      https://stackoverflow.com/a/3117841/1223901

      还有我的问题解决方案

      我希望这对其他人有帮助,就像对我有帮助一样。

      Rgds, iVieL

      【讨论】:

        【解决方案5】:

        有关同时使用应用程序级别身份验证和 HTTP 基本身份验证的示例,请参阅我的 previous posts 之一。

        【讨论】:

          【解决方案6】:

          我遇到了同样的问题,在这里找到了解决方案:

          http://www.mastertheboss.com/web-interfaces/336-jax-ws-basic-authentication.html?start=1

          祝你好运

          【讨论】:

          • 谢谢(最好在此处复制/粘贴解决方案...:P)
          【解决方案7】:

          BindingProvider.USERNAME_PROPERTY 和 BindingProvider.PASSWORD_PROPERTY 匹配 HTTP 基本身份验证机制,在 HTTP 级别而不是在应用程序或 servlet 级别启用身份验证过程。

          基本上,只有 HTTP 服务器知道用户名和密码(最终应用程序根据 HTTP/应用程序服务器规范,例如 Apache/PHP)。 使用 Tomcat/Java,在 web.xml 中添加登录配置 BASIC 和适当的 security-constraint/security-roles(稍后将与用户/真实用户组相关联的角色)。

          <login-config>
              <auth-method>BASIC</auth-method>
              <realm-name>YourRealm</realm-name>
          </login-config>
          

          然后,将 HTTP 服务器(或应用程序服务器)级别的领域与适当的用户存储库连接。对于 tomcat,您可以查看可能适合您需求的 JAASRealm、JDBCRealm 或 DataSourceRealm。

          http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-10-24
            • 1970-01-01
            • 1970-01-01
            • 2017-07-31
            • 1970-01-01
            • 2012-12-17
            • 2014-05-20
            相关资源
            最近更新 更多