tomcat源码阅读之单点登录

一、SSO概念:

单点登录,Single Sign-On,简写为 SSO,是一个用户认证的过程,允许用户一次性进行认证后,就可访问系统中不同的应用;而无需要访问每个应用时,都重新输入用户和密码。

实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统如何验证这个信任的有效性,因此要点也就以下几个:

  • 存储信任
  • 验证信任

 SSO 的实现机制大体分为 Cookie 机制和 Session 机制两大类。

Cookie机制的单点登录:

 

Session机制的单点登录:

 

二、单点登录配置:

这里以tomcat自带的docs和examples应用配置单点登录:

1、在docs应用的WEB-INF/web.xml文件中增加如下内容:

<security-constraint>

    <web-resource-collection>      

        <web-resource-name>MySecurityTest</web-resource-name>

        <url-pattern>/*</url-pattern>

    </web-resource-collection>

    <auth-constraint>

        <role-name>admin-gui</role-name>

        <role-name>manager-gui</role-name>

    </auth-constraint>

</security-constraint>

<login-config>

<auth-method>BASIC</auth-method>

    <realm-name>MySecurityTest</realm-name>

</login-config>

2、由于examples应用已经配置了安全验证,因此可以不用配置;

3、配置tomcat的conf目录下的server.xml文件,增加下面一行:

<Valve className="org.apache.catalina.authenticator.SingleSignOn" />

4、启动tomcat,先访问docs应用,弹出验证窗口,输入用户名或者密码后进入应用,然后再进入examples应用,不用输入用户名和密码,直接进入应用,说明单点登录生效。

三、单点登录实现原理:

 

1、相关实现类说明:

SingleSignOnSessionKey类保存了单点登录时的session信息,保存了sessionId, 应用名称和Host的名称;

SingleSignOnEntry保存了单点登录时的一个SSOID的信息(也就是一个登录账号的信息),保存了用户名、密码、验证方式等基本信息,也保存了SingleSignOnSessionKey类实例的集合,可以通过addSession和removeSession添加和删除;

SingleSignOn作为单点登录实现的服务类,cache保存了SSOID和SingleSignOnEntry的hash键值对,register函数将指定的SSOID和session保存到cache,deregister从cache中删除SSOID,同时调用expire将该SSOID关联的session失效,update从cache中查找指定SSOID的SingleSignOnEntry,并更新其中对应的单点信息,reauthenticate根据保存的单点信息重新登录验证并生成新的principal,然后更新缓存里面的principal,removeSession根据SSOID在cache中查找SingleSignOnEntry,然后从SingleSignOnEntry实例中删除对应的session,如果该SingleSignOnEntry中关联的session都已经被删除了,则调用deregister释放该SSOID对应的单点信息;associate会调用addSession添加单点登录的session;

2、SingleSignOn类集成自ValveBase类,说明他也是一个阀,只是他是挂在host的pipeline上的,因此他的invoke总是先于context.pipeline里面的valve的invoke执行;

3、单点登录代码流程解读:

a)   由于SingleSignOn阀是挂在host上,因此第一次验证请求总是先到达SingleSignOn阀的invoke方法,由于此时SingleSignOn中的缓存还没缓存任何的SSO信息,且cookie中不含有单点登录的cookie信息,所以SingleSignOn阀的invoke方法不做任何处理;

 

b)   BasicAuthenticator验证器在验证成功后,会调用register方法保存principal信息:

 

c)   AuthenticatorBase的register方法中首先给cookie中添加JSESSIONIDSSO值:

 

然后将该SSOID和单点信息注册到SingleSignOn中:

 

d)   当客户端再次访问请求其他需要安全验证的应用时,request请求首先到达SingleSignOn阀的invoke方法, SingleSignOn根据cookie中的SSOID值查找对应的SingleSignOnEntry,将SingleSignOnEntry中的principal设置到request中:

 

e)   然后request请求到达AuthenticatorBase的invoke方法,再到达BasicAuthenticator.authenticate方法,在这里首先从request取出principal,如果取到了则直接返回验证成功而不用再让用户去输入用户名密码验证:

 

原文地址:https://www.cnblogs.com/laoxia/p/7992600.html