如何从HTTP基本身份验证获取密码

42

我正在使用Java进行HTTP基本身份验证。

我的Servlet发送JMS消息,但是在创建连接时需要提供用户名和密码以进行身份验证:

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

我可以通过 HttpServletRequest.getUserPrincipal() 方法获取用户名,但似乎没有办法检索密码。我该如何解决这个问题?

3个回答

135
您所提到的密码很可能与用户登录时提供的密码不同。尽管问题中的用例不清楚,但似乎您正在尝试使用外部用户提供的用户名/密码来创建到JMS Connection Factory的连接。在我的看法中,这在架构上并不安全。您应该仅使用一个凭据来连接需要受保护的ConnectionFactory(将其视为db连接)。更好的方法是使用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()方法。 - Jin Kim
1
谢谢。它起作用了,但需要微调。但是你不能将'Base64'称为静态类。我这样做了: Base64 b = new Base64(); String credentials = new String(b.decode(base64Credentials), Charset.forName("UTF-8")); - Ankit Singh
1
请注意,授权类型(“Basic”)是不区分大小写的,就像所有HTTP标头字段一样。请参见:https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 因此,如果标头使用不同的大小写方式,则上述代码可能会在.startsWith("Basic")处失败。 - Adriaan Koster
@AdriaanKoster 您是正确的,它是不区分大小写的,但并不是因为它是一个头字段(它是一个头值)。这是因为RFC7235规定了这一点:HTTP提供了一个简单的挑战-响应身份验证框架,服务器可以用它来挑战客户端请求,客户端可以用它来提供身份验证信息。**它使用不区分大小写的标记作为识别身份验证方案的手段**,然后是实现该方案所需的其他信息。(强调添加) - imgx64

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

-1

那些正在寻找答案的人,即使问题早已被提出,这里是我的解决方案...

 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 导入的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接