java实现单点登录
地球日是几月几日-入党积极分子自我总结
java实现单点登录
目标:使用域账户单点登录,并且IE浏览器能自动登录
查相关资料,知道HTTP协议中有401这
个状态表示用户未
授权,要求NTLM方式提供用户信息时,IE会自动取当前
windows
账户,其他浏览器会弹出对话框要求用户输入。服
务器得到用户信息后交给域控验证。 以上是原理,I
IS服务
器是提供这样的实现,只需简单配置。但java服务器,如
tomcat、jbos
s,都没有这样的功能,但在网上很容易搜到了
一个第三方的开源项目实现了这个功能,他是jcifs
使用了
最新版1.3.14,使用中首先出现了怪现象,问题A:jboss启
动后,第一个发
出请求的浏览器能正常进行当前用户的验
证,以后的都报用户名或密码错误。
调试了好久,最终在
每次验证完成后disconnect一下,问题就解决了。 好景不长,
新问题出现了,问题B:项目在公司内部上线后,不停有用
户登录不上,报500错误:the
parameter is incorrect 为解决
问题B,找了域控相关负责人,他提供了一些
jcifs的配置方
式,包括说在配置中要指定一个连接域控的用户名密码,但
所有配置都不见
效,最后他给了一个另外的域控IP,换上后
居然不再有人报500错误了。 据了解,这个不出错的域
控
是老版本的,2003系统,出错的域控是2008系统。问题算
是解决了吗?没有。因为公
司马上要将所有域控都升级了,
到时没有老版的域控给我们系统验证了。 查找解决方案
途
中,对问题A有了新发现,其实不用改代码,只要在配置中
指定一个连接域控的用户名密码即
可。虽然不知道原因。 再
后来,一个同学通过抓包,发现了出500错的规律,查资料
后,怀
疑出错用户都是使用vista或win7用户,并得到了证
实。原因是vista或win7默认采用
NTLM2协议验证,JCIFS
不支持NTLM2。 但或许你会问,这跟新老域控有什么关系。这样解释:首先老版本域控也不支持NTLM2或默认采用了
NTLM协议;其次,vista和w
in7系统默认采用HTLM2并
在服务器要求NTLM是也兼容NTLM。这样vista和win7
用
户在老域控下就使用了NTLM验证,在新域控下使用了
NTLM2验证。
根据这位提供的宝贵资料,Google关键字
NTLM2 jcifs,果然找到了答案
http:#ntlmv2
http:
引用
Q: Does jCIFS support NTLMv2? A: Yes. As of
1.3.0, JCIFS
fully supports NTLMv2 and uses it
by default. Note: The NTLM
HTTP SSO Filter
that used to be included with JCIFS cannot
support NTLMv2. See the above question for
details. 引用
Q: How do I do NTLM
HTTP authentication (a.k.a Single Sign
On) for
my website? A: See 引用
Jespa is a complete
NTLM implementation in 100% Java that
properly
implements both the server and client side of
NTLMv2,
NTLMv1, NTLM2 Session Security and Key
Exchange. Of
particular interest to users of
the old JCIFS SSO Filter, Jespa can
properly
authenticate NTLMv2 clients just like a Windows
server does (using the NetrLogonSamLogon
DCERPC call over
NETLOGON w Secure Channel)
and it includes an HTTP SSO
Servlet Filter.
Note: Jespa uses JCIFS for DCERPC transport
and some basic client side NTLM calculations.
Jespa is not
Open Source (although it is free
for up to 25 users). Please
contact IOPLEX
Software support if you have any questions
regarding Jespa. 但这个不是开源的,也可能是有限制的(free
for up to 25 users),于是有自己修改jcifs的冲动。 但是...
引
用
Note: The old SSO Filter that used
to be included with JCIFS
used a
NTLMv2
and has therefore been removed from the JCIFS
package. 为什么呢?
引用
Now regarding your question about the HTTP
Filter not
supporting NTLMv2: The JCIFS NTLM
HTTP Authentication
Filter uses a
technique whereby the web server simply
marshals the NTLM
challenge-response tokens
between the browser and an SMB
server.
Specifically, when the browser triggers the
Filter, JCIFS
connects to
an SMB server
(the
challenge
computes NTLM password
hashes using the DC's challenge and
the user's
password and sends them to the Filter which
just forwards them
to the
SMB server as
if it were authenticating itself. Meaning, the
browser
thinks it's authenticating with
the web server when it's really
authenticating directly with the DC. This
technique works fine with NTLMv1
however it
cannot work with NTLMv2. The
NTLMv2 challenge also
consists of
information
other
things). That target
information is factored into the calculations
of
the password hashes. So the problem is
that target information
for the
web
server is different from the target information
for the
domain
controller and therefore
the password hash computation will be
wrong
as the browser will expect target information
for the web server
and
not the domain
controller. This is done specifically to thwart
the middle
NTLM
HTTP Filter
cannot be used with NTLMv2. Finally, the JCIFS
NTLM HTTP Authentication Filter is a hack. It
is a
hack that has worked quite well and to
our knowledge is secure
but it
is
not a correct implementation of an NTLM
authentication
acceptor. A
proper
implementation would do as IIS would do which in
the
case of
NTLM would be to use the
DCERPC NETLOGON service.
Specifically, the
web server would generate it's own random
challenge with the
proper
target
information, send that to the browser, collect the
password
hashes and then call the
NetrSamLogon RPC with the challenge
that we
generated and the corresponding password
hashes. Or, according
to the
Heimdal
project, it is also possible to use a form of
Kerberos
digest
authentication to
validate this information. 看来要支持
NTLM2方式的域验证,不是
简单的修改jcifs,而是要去实
现一个协议。况且这方面文档又很难找,真的是不太可能。
最后只能是折中办法:要么域控采用NTLM,要么客户端
NTLM,就是不能两者都是NTLM2。
域控降级到NTLM的
方案被否定,不能为了一个应用而影响所有。所以只能限定
客户端使用NTLM。 我们采用当出错时显示帮助页面的方
式,引导用户修改本地配置LM身份认证
级别。可以在本地
安全此略里配置,或者提供一个注册表文件,将
HKEY_LOCAL_MA
CHINESystemCurrentControlSetContro
lLsaLMCompat
ibilityLevel 修改为1即可