【问题标题】:How to get password from HTTP basic authentication如何从 HTTP 基本身份验证中获取密码
【发布时间】:2013-04-06 16:50:45
【问题描述】:

我在 Java 中使用 HTTP BASIC 身份验证。

我的 Servlet 发送一条 JMS 消息,但我需要在创建连接时提供用户和密码来验证自己:

javax.jms.ConnectionFactory.createConnection(String username, String password)

我可以从 HttpServletRequest.getUserPrincipal() 中检索用户名。但似乎没有办法找回密码。我该如何解决?

【问题讨论】:

    标签: java servlets jms basic-authentication


    【解决方案1】:

    您所指的密码很可能与用户在登录时提供的密码不同。虽然问题中的用例不清楚,但您似乎正在尝试使用外部用户提供的用户名/密码来创建与 JMS 连接工厂的连接。这对我来说在架构上听起来并不安全。您应该只使用一个凭据连接到需要保护的 ConnectionFactory(将其视为数据库连接)。更好的是使用 JNDI 来查找 ConnectionFactory 并绕过用户名/密码管理的东西。

    但是,如果您必须使用该技术,可以使用以下代码块。我从 Gitblit 项目中复制它,因为它在我的 eclipse 中打开了

    使用 Java8 Base64 类:

    final String authorization = httpRequest.getHeader("Authorization");
    if (authorization != null && authorization.toLowerCase().startsWith("basic")) {
        // Authorization: Basic base64credentials
        String base64Credentials = authorization.substring("Basic".length()).trim();
        byte[] credDecoded = Base64.getDecoder().decode(base64Credentials);
        String credentials = new String(credDecoded, StandardCharsets.UTF_8);
        // credentials = username:password
        final String[] values = credentials.split(":", 2);
    }
    

    【讨论】:

    • 您对架构的看法是正确的。我已经放弃了这种方法,只是采用了无凭据的 javax.jms.ConnectionFactory.createConnection() 方法。
    • 谢谢。它有效,但有一点调整。但是您不能将“Base64”称为静态类。我做了: Base64 b = new Base64(); String credentials = new String(b.decode(base64Credentials), Charset.forName("UTF-8"));
    • 请注意,授权类型(“基本”)不区分大小写,就像所有 HTTP 标头字段一样。请参阅:w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 因此,如果标头使用不同的大小写,上述代码可能会在 `.startsWith("Basic") 失败
    • @AdriaanKoster 你是对的,它不区分大小写,但不是因为它是一个标题字段(它是一个标题值)。它不区分大小写,因为RFC7235 是这样说的:HTTP provides a simple challenge-response authentication framework that can be used by a server to challenge a client request and by a client to provide authentication information. **It uses a case-insensitive token as a means to identify the authentication scheme**, followed by additional information necessary for achieving authentication via that scheme.(添加了重点)
    【解决方案2】:

    用户名和密码最初是在 HTTP Authorization 标头(base64 编码)中发送的,因此您可以使用它;但如果用户使用 cookie 维护会话,他们不一定每次都发送该标头。

    【讨论】:

      【解决方案3】:

      那些在很久以前就问过问题的人正在寻找答案,这是我的解决方案..

       private void authenticate(HttpServletRequest request){
          String upd=request.getHeader("authorization");
          String pair=new String(Base64.decodeBase64(upd.substring(6)));
          String userName=pair.split(":")[0];
          String password=pair.split(":")[1];    
      }
      

      Base64是从-org.apache.commons.codec.binary.Base64导入的;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-08
        • 1970-01-01
        • 2019-07-22
        • 1970-01-01
        • 2016-09-14
        • 2021-03-21
        • 2011-11-12
        • 2011-05-05
        相关资源
        最近更新 更多