接到一个case,客户反应我们的监控系统访问不了他们的网络,而监控系统所在的机子,是可以通过浏览器访问的。马上获取相关log进行分析,找到以下报错
java.io.IOException: Authentication failure
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1319)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
。。。。。。。。
。。。。。。。。
。。。。。。。。
at sun.reflect.GeneratedMethodAccessor72.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
。。。。。。。。
。。。。。。。。
at com.sun.proxy.$Proxy78.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
报错是跟认证相关的,查ReleaseNotes,我们产品只支持HTTP Basic Authentication,搭建了一个简单的Basic Authentication小应用,用我们产品来监控,乱填一些认证信息,得到以下401报错,初步推测,用户遇到的问题跟账户密码是否正确无关。
java.io.IOException: Server returned HTTP response code: 401 for URL: http://localhost:8011/hash/BasicAuthServlet
at sun.reflect.GeneratedConstructorAccessor88.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1491)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1485)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
。。。。。。。。
。。。。。。。。
。。。。。。。。
考虑到用户是把系统部署在windows环境,windows环境常用的认识方式有NTLM,于是把测试应用改为NTLM认证,再次用我们产品来监控,得到了跟客户类似的认证相关的报错"java.io.IOException: Authentication failure",于是怀疑客户的系统是使用了NTLM认证。
final String authTypeStr = "NTLM"; //"Basic realm"
response.setHeader("WWW-authenticate", authTypeStr);
怎样才能确定客户是真的使用了NTLM认证呢?想到了一个很好的工具wget,使用的是windows版本的,让客户执行以下语句,并把结果给我们。
wget -dv --http-user=<username> --http-password=<password> --output-file=debug-log.txt --output-document=doc.txt <monitoring url>
拿到wget结果后,一下子就看到,客户的系统果然是使用NTLM认证的,于是,把实际情况反馈给客户,系统暂时不支持NTLM认证,问题得到解决。
---request begin---
GET /default.aspx HTTP/1.0
User-Agent: Wget/1.10.2
Accept: */*
Authorization: NTLM