1.1 分析:windows域登录过程采用Kerberose v5协议进行登录,过程非常复杂,并且登录中身份认证以及域的权
限整合在一起。要剥离身份认证和权限赋权非常困难。要整合现有的SSO服务器,可以考虑,采用windows域控制器
统一管理用户,SSO服务器采用该域控制器的Active Directory中的用户信息。windows工作站(比如winxp)登录
域过程中,保持原域登录的过程,在其中添加SSO服务器的登录过程。
1.2 实现:通过修改GINA模块,在windows工作站(比如winxp)登录域过程中,winlogon调用GINA组模块,把用户
提供的账号和密码传达给GINA,由GINA负责在域控制器中以及SSO服务器中账号和密码的有效性验证,然后把验证
结果反馈给Winlogon程序,只有域控制器和SSO服务器同时认证成功,才是登录成功。
另外开发一个DLL程序,暂时称为SSOLogin模块,GINA在登录成功后,将SSO的登录信息传递给SSOLogin模块,动力
工作站在启动时,首先调用SSOLogin模块,判断已经登录的用户,然后通过动力工作站访问其他应用时,就可以通
过SSO服务器进行单点登录。
1.3 技术点:
(1)通过jCIFS实现SSO服务器在Active Directory进行域登录。
(2)采用WFC开发框架对GINA.dll进行修改,在注册表中进行注册
1.4 风险难点:(1)、windows域登录过程的分析与改造。(2)、windows的应用不开源,代码分析会比较困难。
1.5 其他:是否还考虑linux操作系统加入windows域的过程?
1.6 winxp登录域过程如下:
(1).用户首先按Ctrl+Alt+Del组合键。
(2).Winlogon检测到用户按下SAS键,就调用GINA,由GINA显示登录对话
框,以便用户输入账号和密码。
(3).用户选择所要登录的域和填写账号与密码,确定后,GINA将用户输入的
信息发送给LSA进行验证。
(4).在用户登录到本机的情况下,LSA将请求发送给Kerberos验证程序包。
通过散列算法,根据用户信息生成一个密钥,并将密钥存储在证书缓存区中。
(5).Kerberos验证程序向KDC(Key Distribution Center--密钥分配中心)发
送一个包含用户身份信息和验证预处理数据的验证服务请求,其中包含用户证
书和散列算法加密时间的标记。
(6).KDC接收到数据后,利用自己的密钥对请求中的时间标记进行解密,通
过解密的时间标记是否正确,就可以判断用户是否有效。
(7).如果用户有效,KDC将向用户发送一个TGT(Ticket-Granting Ticket--
票据授予票据)。该TGT(AS_REP)将用户的密钥进行解密,其中包含会话密钥、
该会话密钥指向的用户名称、该票据的最大生命期以及其他一些可能需要的数
据和设置等。用户所申请的票据在KDC的密钥中被加密,并附着在AS_REP中。
在TGT的授权数据部分包含用户账号的SID以及该用户所属的全局组和通用组的
SID。注意,返回到LSA的SID包含用户的访问令牌。票据的最大生命期是由域
策略决定的。如果票据在活动的会话中超过期限,用户就必须申请新的票据。
(8).当用户试图访问资源时,客户系统使用TGT从域控制器上的Kerberos
TGS请求服务票据(TGS_REQ)。然后TGS将服务票据(TGS_REP)发送给客户。该
服务票据是使用服务器的密钥进行加密的。同时,SID被Kerberos服务从TGT复
制到所有的Kerberos服务包含的子序列服务票据中。
(9).客户将票据直接提交到需要访问的网络服务上,通过服务票据就能证明
用户的标识和针对该服务的权限,以及服务对应用户的标识。
1. 前言
技术这东西吧,看别人写的好像很简单似的,到自己去写的时候就各种问题,“一看就会,一做就错”。网上关于实现SSO的文章一大堆,但是当你真的照着写的时候就会发现根本不是那么回事儿,简直让人抓狂,尤其是对于我这样的菜鸟。几经曲折,终于搞定了,决定记录下来,以便后续查看。先来看一下效果
2. 准备
2.1. 单点登录
最常见的例子是,我们打开淘宝APP,首页就会有天猫、聚划算等服务的链接,当你点击以后就直接跳过去了,并没有让你再登录一次
下面这个图是我再网上找的,我觉得画得比较明白:
可惜有点儿不清晰,于是我又画了个简版的:
重要的是理解:
2.2. OAuth2
推荐以下几篇博客
《 OAuth 2.0 》
《 Spring Security对OAuth2的支持 》
3. 利用OAuth2实现单点登录
接下来,只讲跟本例相关的一些配置,不讲原理,不讲为什么
众所周知,在OAuth2在有授权服务器、资源服务器、客户端这样几个角色,当我们用它来实现SSO的时候是不需要资源服务器这个角色的,有授权服务器和客户端就够了。
授权服务器当然是用来做认证的,客户端就是各个应用系统,我们只需要登录成功后拿到用户信息以及用户所拥有的权限即可
之前我一直认为把那些需要权限控制的资源放到资源服务器里保护起来就可以实现权限控制,其实是我想错了,权限控制还得通过Spring Security或者自定义拦截器来做
3.1. Spring Security 、OAuth2、JWT、SSO
在本例中,一定要分清楚这几个的作用
首先,SSO是一种思想,或者说是一种解决方案,是抽象的,我们要做的就是按照它的这种思想去实现它
其次,OAuth2是用来允许用户授权第三方应用访问他在另一个服务器上的资源的一种协议,它不是用来做单点登录的,但我们可以利用它来实现单点登录。在本例实现SSO的过程中,受保护的资源就是用户的信息(包括,用户的基本信息,以及用户所具有的权限),而我们想要访问这这一资源就需要用户登录并授权,OAuth2服务端负责令牌的发放等操作,这令牌的生成我们采用JWT,也就是说JWT是用来承载用户的Access_Token的
最后,Spring Security是用于安全访问的,这里我们我们用来做访问权限控制
4. 认证服务器配置
4.1. Maven依赖
这里面最重要的依赖是:spring-security-oauth2-autoconfigure
4.2. application.yml
4.3. AuthorizationServerConfig(重要)
说明:
4.4. WebSecurityConfig(重要)
4.5. 自定义登录页面(一般来讲都是要自定义的)
自定义登录页面的时候,只需要准备一个登录页面,然后写个Controller令其可以访问到即可,登录页面表单提交的时候method一定要是post,最重要的时候action要跟访问登录页面的url一样
千万记住了,访问登录页面的时候是GET请求,表单提交的时候是POST请求,其它的就不用管了
4.6. 定义客户端
4.7. 加载用户
登录账户
加载登录账户
4.8. 验证
当我们看到这个界面的时候,表示认证服务器配置完成
5. 两个客户端
5.1. Maven依赖
5.2. application.yml
这里context-path不要设成/,不然重定向获取code的时候回被拦截
5.3. WebSecurityConfig
说明:
5.4. MemberController
5.5. Order项目跟它是一样的
5.6. 关于退出
退出就是清空用于与SSO客户端建立的所有的会话,简单的来说就是使所有端点的Session失效,如果想做得更好的话可以令Token失效,但是由于我们用的JWT,故而撤销Token就不是那么容易,关于这一点,在官网上也有提到:
本例中采用的方式是在退出的时候先退出业务服务器,成功以后再回调认证服务器,但是这样有一个问题,就是需要主动依次调用各个业务服务器的logout
6. 工程结构
附上源码: https://github.com/chengjiansheng/cjs-oauth2-sso-demo.git
7. 演示
8. 参考
https://www.cnblogs.com/cjsblog/p/9174797.html
https://www.cnblogs.com/cjsblog/p/9184173.html
https://www.cnblogs.com/cjsblog/p/9230990.html
https://www.cnblogs.com/cjsblog/p/9277677.html
https://blog.csdn.net/fooelliot/article/details/83617941
http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/
https://www.cnblogs.com/lihaoyang/p/8581077.html
https://www.cnblogs.com/charlypage/p/9383420.html
http://www.360doc.com/content/18/0306/17/16915_734789216.shtml
https://blog.csdn.net/chenjianandiyi/article/details/78604376
https://www.baeldung.com/spring-security-oauth-jwt
https://www.baeldung.com/spring-security-oauth-revoke-tokens
https://www.reinforce.cn/t/630.html
9. 文档
https://projects.spring.io/spring-security-oauth/docs/oauth2.html
https://docs.spring.io/spring-security-oauth2-boot/docs/2.1.3.RELEASE/reference/htmlsingle/
https://docs.spring.io/spring-security-oauth2-boot/docs/2.1.3.RELEASE/
https://docs.spring.io/spring-security-oauth2-boot/docs/
https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/
https://docs.spring.io/spring-boot/docs/
https://docs.spring.io/spring-framework/docs/
https://docs.spring.io/spring-framework/docs/5.1.4.RELEASE/
https://spring.io/guides/tutorials/spring-boot-oauth2/
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#core-services-password-encoding
https://spring.io/projects/spring-cloud-security
https://cloud.spring.io/spring-cloud-security/single/spring-cloud-security.html
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/java-security.html
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-redis.html#boot-spring-configuration
原文链接:https://www.cnblogs.com/cjsblog/p/10548022.html
两个站点如果在同域下,那么它们之间是可以共享cookie的。简单的说就是这种同域下不同站点的sso实现可以通过cookie来实现,当用户访问这个域下面的任意站点时,浏览器都会将这个cookie发送给站点对应的系统。举个简单的例子:
站点1: www.ssotest.com/site1
站点2: www.ssotest.com/site2
从上面可以看出,这两个站点是在相同域名( www.ssotest.com )下,那么从站点1登录时,会在浏览器存储一些cookie,当在站点1下做任何操作时都会将这些cookie发送给站点1,同理,当访问站点2时,由于站点2和站点1在同一个域名下面,所以也会将这些cookie发送给站点2,所以这样的话就能够实现SSO了。可参考图1:
指相同父域,但是不同二级域名的单点登录,例如如下有两个站点:
从上面可以看出,它们的父域都是.ssotest.com,但是它们的二级域名不相同,所有如果在subsite1站点直接创建cookie,那么subsite2站点是不能够获取到subsite1的cookie的,所以如果直接在subsite1站点登录,将无法实现单点登录,那么如何才能实现这种情况的SSO呢?
实现它们之间的SSO最关键的一点是:实现cookie共享和session共享,保持二者的sessionId相同。
解决方案如下:
1.如果是使用的spring boot框架的后台应用,只需要在application.properties配置文件中添加上如下配置即可(因为内嵌tomcat):
2.如果使用外部tomcat,那么需要在server.xml文件中添加如下配置:
要实现这种跨域方式的SSO,有两种方式:
1.使用cookie,在各个应用之间重定向
2.使用单独的SSO服务器(更优)
那么下面详细的介绍上面这两种方式,以如下三个站点(应用)来具体描述:
这种方式比较简单,当用户在上面三个站点中的任意一个站点登录成功时,必须在浏览器中同时设置其他站点的cookie信息。
例如:当用户登录site1站点,并且验证通过之后,浏览器会存储一份site1站点的cookie信息,这时,为了实现单点登录(为了在site2站点和site3站点无需登录),那么我们需要在浏览器设置site2站点和site3站点的cookie信息,因此,在用户登录site1站点的请求响应之前,需要从siteId1站点重定向到site2站点和site3站点去设置cookie信息,这样就可以保证,在任意站点登录成功之后,在浏览器也有其他站点的cookie信息。下图2可具体展示其中流程:
这种方式其实过程比较简单,只需要确保登录其中一个站点在浏览器设置cookie其他站点都在浏览器设置对应cookie,就可以实现单点登录了(单点退出是一样的道理,一个退出清除cookie,其他也清除)。
但是这种方式有一个非常明显的缺点是:这里举例是3个站点,如果是几十个上百个站点再使用这种方式将非常影响效率。
这种方式需要借助一个单独的SSOServer,相对于上一种方式,这种方式就不需要将每个站点的cookie信息都保存在浏览器上,浏览器只需要保存SSOServer的cookie信息。将这个cookie信息用于需要做单点登录的所有站点中。
对于这种方式,在浏览器对于任意一个站点的请求都将会先重定向到SSOServer去验证代表当前用户的cookie是否存在,如果存在,那么将验证成功后的跳转页面发送给浏览器,否则将跳转到登录页面提示用户登录。可参考如下图3模型:
由于site1和site2的单点登录与site1、site2、site3之间的单点登录是同样道理的(因为登录site1后去访问site2和site3的流程都是相同的),所以,这里借助site1和site2的单点登录来说明这种方式。
下面分为三部分(三张图)来说明这种方式的单点登录:
第一部分:未在SSOServer登录,浏览器请求site1需要验证的页面,在SSOServer获取不到cookie,被重定向到site1登录界面,提示登录,流程如下图4:
在SSOServer登录的情况下,其他所有站点的登录情况都如site2,图6所示的流程,可见使用SSOServer的方式会方便许多。
以上就是SSO三种情况的实现方式。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)