最近 hadoop 一系列软件都给加上了 kerberos 认证,整体来说还算顺利,各组件也都继续正常工作,唯独 storm ui,个天杀的在 windows 上打不开。
HTTP ERROR: 403
Problem accessing /index.html. Reason:
GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
Powered by Jetty://
ok, 现在就需要实现能在 windows 上访问带有 kerberos 权限验证的 storm ui 了。
1. 找个 kerberos 在 windows 上的实现,能 kinit 啥的
我这里找到一个 MIT 的实现. 我下载的是 64-bit MSI Installer kfw-4.1-amd64.msi, 10812k.
安装完了它就自动的在 PATH 里面加上了自己的目录,但是!!! 我这里安装的 oracle jdk 里面也带了一些 kinit, ktab, klist 等软件,而且我这里 jdk 的顺序靠前,所以输入 kinit 、klist 的时候
执行的其实是 jdk 里面的工具,而我没有留心去找怎么配置 jdk 里面的,我的做法就是把 kfw 的 path 弄得靠前一点。
怎么通过 kinit 登录就不讲了吧。。
2. 配置浏览器
参考 http://storm.apache.org/releases/1.1.1/SECURITY.html#ui-logviewer,打开 firefox 浏览器 (为啥不是 chrome 及 ie 后面会讲), 输入 about:config 修改配置项 network.negotiate-auth.trusted-uris double-click 如图
3. 验证
配置完成后验证一下还是要有的,使用 firefox 打开 storm ui 的地址试一下吧。
4. chrome 及 IE 目前未能测试通过。先将细节展示出来
4.1. firefox 执行流程
4.1.1 firefox 像对待普通网站一样去访问 storm ui 结果服务器拒绝了它并返回了 401 需要授权
4.1.2 firefox 懵了一下并携带密钥再去访问了一次 storm ui,这次 storm ui 接受了它并告诉它 cookie 是什么以及一个验证的密钥
4.1.3 firefox 觉得 storm ui 的密钥是对的并非常信任他,以后访问的时候就带着 cookie 去请求了。
4.2 Chrome 为什么不行呢?
4.2.1 chrome 觉得自己知道 storm ui 需要 kerberos 授权,所以主动带着不知道哪里来的 很短的 密钥 去访问 storm ui,storm 果断拒绝了 chrome 的请求并返回 403.
4.2.2 over
4.3 IE 比 Chrome 好一点点,但是也是一个悲剧
4.3.1 IE 并不知道 storm ui 需要 kerberos 授权,直接就去访问了,服务器无情的拒绝它并向它扔了一个 401 状态码。
4.3.2 IE 意识到需要表明自己的身份然后拿了一个非常短的密钥串再次请求服务器并遭到拒绝,这次服务器返回了一个 403 。(chrome: 呵呵)
4.3.3 全剧终
更新:
为什么 chrome 和 IE 的 Auth 串这么短呢?
stackoverflow 上相关讨论 https://stackoverflow.com/questions/5597573/how-to-find-if-ntlm-or-kerberos-is-used-from-www-authenticate-negotiate-header 里面说了, 这里贴一下精简版:
If the Authorization token begins with "YII" then Kerberos is used, but if it begins with "TlR" then Kerberos is not used.
For example Kerberos:
Authorization: Negotiate YIIVDAYGKwYBE...
Not Kerberos:
Authorization: Negotiate TlRMTVNTUA...
所以说 chrome 和 IE 的那个串生成方式不对。。
2017/08/29 更新:
https://www.chromium.org/developers/design-documents/http-authentication 上如是说:
Negotiate external libraries
On Windows, Negotiate is implemented using the SSPI libraries and depends on code in secur32.dll.
On Android, Negotiate is implemented using an external Authentication app provided by third parties. Details are given in Writing a SPNEGO Authenticator for Chrome on Android. The AuthAndroidNegotiateAccountType policy is used to tell Chrome the Android account type provided by the app, hence letting it find the app.
On other platforms, Negotiate is implemented using the system GSSAPI libraries. The first time a Negotiate challenge is seen, Chrome tries to dlopen one of several possible shared libraries. If it is unable to find an appropriate library, Chrome remembers for the session and all Negotiate challenges are ignored for lower priority challenges.The GSSAPILibraryName policy can be used to specify the path to a GSSAPI library that Chrome should use.Otherwise, Chrome tries to dlopen/dlsym each of the following fixed names in the order specified:
- OSX: libgssapi_krb5.dylib
- Linux: libgssapi_krb5.so.2, libgssapi.so.4, libgssapi.so.2, libgssapi.so.1
Chrome OS follows the Linux behavior, but does not have a system gssapi library, so all Negotiate challenges are ignored.
- Support NTLMv2 on Mac and Linux. Our portable NTLM code supports NTLMv1 only.
- Support GSSAPI on Windows [for MIT Kerberos for Windows or Heimdal]
- Warn about Basic authentication scheme over unencrypted channels.
参考:
1. storm ui doc http://storm.apache.org/releases/1.1.1/SECURITY.html#ui-logviewer
2. mit kerberos http://web.mit.edu/kerberos/dist/index.html