[英]HTTP digest authentication with HttpUrlConnection
我正在尝试使用摘要身份验证连接到我机器上的 Tomcat Web 服务器。 我正在使用tomcat的内存领域。 以下是服务器的配置方式:
1) 在 server.xml 中:
<Realm className="org.apache.catalina.realm.MemoryRealm" digest="MD5" />
2) 在 tomcat-users.xml 中
<user username="testuser" password="81dc9bdb52d04dc20036dbd8313ed055" roles="test"/>
3)在我的web项目的web.xml中:
<auth-method>DIGEST</auth-method>
如您所见,我已将摘要方法指定为“MD5”,并使用 Tomcat 的digest.sh 对密码进行了加密。
这是我在客户端的代码:
private static void testGet() throws IOException {
// Create a URL
URL test = new URL("http://localhost:8080/TestWebProject/TestServlet");
// Open a connection to the URL
HttpURLConnection conn = (HttpURLConnection) test.openConnection();
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
// Digest password using the MD5 algorithm
String password = "1234";
md5.update(password.getBytes());
String digestedPass = digest2HexString(md5.digest());
// Set header "Authorization"
String credentials = "testuser:" + digestedPass;
conn.setRequestProperty("Authorization", "Digest " + credentials);
// Print status code and message
System.out.println("Test HTTP GET method:");
System.out.println("Status code: " + conn.getResponseCode());
System.out.println("Message: " + conn.getResponseMessage());
System.out.println();
}
private static String digest2HexString(byte[] digest)
{
String digestString="";
int low, hi ;
for(int i=0; i < digest.length; i++)
{
low = ( digest[i] & 0x0f ) ;
hi = ( (digest[i] & 0xf0)>>4 ) ;
digestString += Integer.toHexString(hi);
digestString += Integer.toHexString(low);
}
return digestString ;
}
我认为我的客户端代码没问题,服务器的配置也是如此。 尽管服务器不断向我发送状态代码 401,并显示消息“未授权”。 由于我不是经验丰富的 Java 开发人员,我想问一下是否有人对我的实现有想法或看到错误。
提前谢谢你!
摘要式身份验证远比发送username:password
复杂得多(这实际上是基本身份验证......并且username:password
元组需要进行 Base64 编码!)。
您可以在此处阅读有关摘要的所有信息。
如果您不需要使用HttpUrlConnection
看看这两个项目:
他们都已经开箱即用地支持 Digest(和其他有用的东西)。
HttpUrlConnection 适用于简单的工作,但如果您想要具有更高级功能(如摘要身份验证)的东西,我建议使用Commons HTTP Client。
我可以按照以下代码完成工作,如果我遗漏了什么,请告诉我;
DefaultHttpClient httpclient = new DefaultHttpClient();
ResponseHandler<String> responseHandler = new BasicResponseHandler();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope("localhost", 8080),
new UsernamePasswordCredentials("username", "password"));
HttpGet httpget = new HttpGet(urlStr);
System.out.println("executing request" + httpget.getRequestLine());
String response = httpclient.execute(httpget, responseHandler);
System.out.println("Response :: " + response);
使用以下代码,如果您的服务器不需要 'opaque' return ,它就可以工作。
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials(username, password));
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
HttpResponse response = httpClient.execute(get);
奇怪的是,摘要式身份验证可以使用此代码在 jdk 上本地运行,而基本身份验证则不能:
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication (
"username",
"password".toCharArray()
);
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.