登录那点事

[TOC]

简单登录


client:提供用户名和密码或者是其他的认证凭证

server:验证client提供的认证凭证,记录登录状态

过程:访问系统时,client必须输入用户名和密码,server进行验证,验证通过后server建立一个叫做session的东西,然后把sessionId通过cookie发送给浏览器,下次登录的时候会带着cookie一起发过来,server从cookie中拿到sessionId就知道已经登录啦。

 cookie和session的作用就是保持client和server的交互状态,这样一来可以将无状态的通信转化成有状态的交互,也就是让server有了“记忆”能力。


多系统登录

现在有三个服务,需要输入三次用户信息,但是如果有成百上千的服务呢?HOW???


参考上面简单登录的原理:服务端如何有了“记忆”能力呢:在client和server之间引入了一个中间层(cookie或者是session)。(题外话:计算机世界的99%的问题都可以通过一个引入一个中间层来解决)

所有我们可以想到一个可行的解决方案:对这个“中间层”做共享。

比如说先登录了A,就有了一个cookie,然后在用cookie去登录其他的系统。但是这样明显是有问题的:

1,cookie不能跨域,比如说a.com产生的cookie是不能传递给b.com的

2,就算cookie可以传递,但是其他系统并没有session来校验这个cookie。

解决方案:

1.cookie做共享可以挂到同一个一级域名下,比如A叫a.corp.com,B叫b.corp.com,C叫c.corp.com,这样cookie不就能共享了嘛

2,将session也做共享,从内存里面拿出来,放入一个大家都能访问的中间层里面,比如说redis。(题外话:又是中间层)

像下面这样:


可以解决多系统登录的问题么?可以解决!!! 但是

1,要共享cookie就必须让所有的系统都在同一个域名下

2,多用户账号的存在。比如张三登录了A,然后去登录B,通过这种方式的话B需要去校验张三这个用户的合法性,此张三可能未必是彼张三!各个业务系统必须自己去维护自己系统的用户,而且用户信息还不止一个。

HOW????

SSO

Single Sign One :单点登录

消除多用户信息的问题,不用各个业务系统自己去维护用户信息,建立一个统一的用户认证中心(中间层:又是我哈哈哈),所有用户的认证工作都交给这个认证中心来完成。各个子业务只需要负责实现自己的业务即可,不在需要关心用户、认证等细节。

大致流程如下:

用户第一次访问A系统:www.a.corp.com,这个时候如果A发现用户没有登录的话,那他需要做的一项操作就是重定向认证中心:www.sso.com/login?redirect=www.a.corp.com。

其中www.sso.com/login就是认证中心的登录地址,redirect=www.a.corp.com就是登录完成后需要跳转到的地址。在认证中心登录之后认证中心会做以下几件事情:

1,建立一个session

2,发放ticket

3,重定向到你的地址,并在浏览器种下cookie信息。注意这个cookie是认证中心服务器的cookie哦。如:ssoid=1,domain=sso.com


需要注意的有两点:

1,进行了两次重定向。第一次是重定向到SSO的服务器,第二次是重定向我们的后端服务器。

2,流程完成后再浏览器种了两个cookie,一个是sso服务器的cookie,一个是子系统A的cookie。


接下来我们访问B系统:

这个时候会有三个cookie:

1,认证中心的cookie    domain:   sso.com  

2,A系统的cookie    domain: a.corp.com

3, B系统的cookie     domain: b.corp.com

本质上就是保存了一个认证中心的cookie和多个子系统的cookie。一般我们称SSO的cookie的对应的会话成为全局会话,各自子系统cookie对应的会话称为局部会话。

解决方案(CAS)

概述

CAS(Central Authentication Service) 是 Yale 大学发起的一个企业级的、开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(属于 Web SSO)。

CAS 开始于 2001 年, 并在 2004 年 12 月正式成为 JA-SIG 的一个项目。

特性

1、  开源的、多协议的 SSO 解决方案;Protocols:Custom Protocol、CAS、OAuth、OpenID、RESTful API、SAML1.1、SAML2.0 等。

2、  支持多种认证机制:Active Directory、JAAS、JDBC、LDAP、X.509 Certificates 等;

3、  安全策略:使用票据(Ticket)来实现支持的认证协议;

4、  支持授权:可以决定哪些服务可以请求和验证服务票据(Service Ticket);

5、  提供高可用性:通过把认证过的状态数据存储在 TicketRegistry 组件中,这些组件有很多支持分布式环境的实现,如:BerkleyDB、Default 、EhcacheTicketRegistry、JDBCTicketRegistry、JBOSS TreeCache、JpaTicketRegistry、MemcacheTicketRegistry 等;

6、  支持多种客户端: Java、 .Net、 PHP、 Perl、 Apache, uPortal 等。

体系结构 

从结构上看,CAS 包含两个部分:CAS Server 和 CAS Client,CAS 需要独立部署,主要负责对用户的认证工作,CAS Server 会处理用户名 / 密码等凭证 (Credentials)。

负责处理对客户端受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。CAS Client一般与 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。过滤从客户端过来的每一个 Web 请求,同时, CAS Client 会分析 HTTP 请求中是否包请求 Service Ticket

术语

 Ticket Granting ticket (TGT) :可以认为是CAS Server根据用户名密码生成的一张票,存在server端

Ticket-granting cookie (TGC) :其实就是一个cookie,存放用户身份信息,由server发给client端

Service ticket (ST) :由TGT生成的一次性票据,用于验证,只能用一次。相当于server发给client一张票,然后client拿着这是个票再来找server验证,看看是不是server签发的。就像是我给了你一张我的照片,然后你拿照片再来问我,这个照片是不是你。。。没错,就是这么无聊。

安全性


TGC安全性:

对于一个 CAS 用户来说,最重要是要保护它的 TGC,如果 TGC 不慎被 CAS Server 以外的实体获得,Hacker 能够找到该 TGC,然后冒充 CAS 用户访问所有授权资源。从基础模式可以看出, TGC 是 CAS Server 通过 SSL 方式发送给终端用户,因此,要截取 TGC 难度非常大,从而确保 CAS 的安全性。TGT 的存活周期默认为 120 分钟。

ST安全性:

ST(Service Ticket)是通过 Http 传送的,因此网络中的其他人可以 Sniffer 到其他人的 Ticket。CAS 通过以下几方面来使 ST 变得更加安全:

1、  ST 只能使用一次

CAS 协议规定,无论 Service Ticket 验证是否成功, CAS Server 都会清除服务端缓存中的该 Ticket,从而可以确保一个 Service Ticket 不被使用两次。

2、  ST 在一段时间内失效

CAS 规定 ST 只能存活一定的时间,然后 CAS Server 会让它失效。默认有效时间为 5 分钟。

3、  ST 是基于随机数生成的

ST 必须足够随机,如果 ST 生成规则被猜出,Hacker 就等于绕过 CAS 认证,直接访问对应的服务。

流程


上图是3个登录场景,分别为:第一次访问www.qiandu.com、第二次访问、以及登录状态下第一次访问mail.qiandu.com。

第一次访问www.qiandu.com

标号1:用户访问http://www.qiandu.com,经过他的第一个过滤器:org.jasig.cas.client.authentication.AuthenticationFilter(cas提供,在web.xml中配置)。主要作用:判断是否登录,如果没有登录则重定向到认证中心

标号2:www.qiandu.com发现用户没有登录,则返回浏览器重定向地址。


首先可以看到我们请求www.qiandu.com,之后浏览器返回状态码302,然后让浏览器重定向到cas.qiandu.com并且通过get的方式添加参数service,该参数目的是登录成功之后会要重定向回来,因此需要该参数。并且你会发现,其实server的值就是编码之后的我们请求www.qiandu.com的地址。

标号3:浏览器接收到重定向之后发起重定向,请求cas.qiandu.com。

标号4:认证中心cas.qiandu.com接收到登录请求,返回登陆页面。


上图就是标号3的请求,以及标号4的响应。请求的URL是标号2返回的URL。之后认证中心就展示登录的页面,等待用户输入用户名密码。

标号5:用户在cas.qiandu.com的login页面输入用户名密码,提交。

标号6:服务器接收到用户名密码,则验证是否有效,验证逻辑可以使用cas-server提供现成的,也可以自己实现。


上图就是标号5的请求,以及标号6的响应了。当cas.qiandu.com即csa-server认证通过之后,会返回给浏览器302,重定向的地址就是Referer中的service参数对应的值。后边并通过get的方式挟带了一个ticket令牌,这个ticket就是ST(数字3处)。同时会在Cookie中设置一个CASTGC,该cookie是网站cas.qiandu.com的cookie,只有访问这个网站才会携带这个cookie过去。

Cookie中的CASTGC:向cookie中添加该值的目的是当下次访问cas.qiandu.com时,浏览器将Cookie中的TGC携带到服务器,服务器根据这个TGC,查找与之对应的TGT。从而判断用户是否登录过了,是否需要展示登录页面。TGT与TGC的关系就像SESSION与Cookie中SESSIONID的关系。点击这里了解Java如何操作Cookie。

TGT:Ticket Granted Ticket(俗称大令牌,或者说票根,他可以签发ST)

TGC:Ticket Granted Cookie(cookie中的value),存在Cookie中,根据他可以找到TGT。

ST:Service Ticket (小令牌),是TGT生成的,默认是用一次就生效了。也就是上面数字3处的ticket值。

标号7:浏览器从cas.qiandu.com哪里拿到ticket之后,就根据指示重定向到www.qiandu.com,请求的url就是上面返回的url。


标号8:www.qiandu.com在过滤器中会取到ticket的值,然后通过http方式调用cas.qiandu.com验证该ticket是否是有效的。

标号9:cas.qiandu.com接收到ticket之后,验证,验证通过返回结果告诉www.qiandu.com该ticket有效。

标号10:www.qiandu.com接收到cas-server的返回,知道了用户合法,展示相关资源到用户浏览器上。


第二次访问www.qiandu.com

标号11:用户发起请求,访问www.qiandu.com。会经过cas-client,也就是过滤器,因为第一次访问成功之后www.qiandu.com中会在session中记录用户信息,因此这里直接就通过了,不用验证了。


标号12:用户通过权限验证,浏览器返回正常资源。


访问mail.qiandu.com

标号13:用户在www.qiandu.com正常上网,突然想访问mail.qiandu.com,于是发起访问mail.qiandu.com的请求。

标号14:mail.qiandu.com接收到请求,发现第一次访问,于是给他一个重定向的地址,让他去找认证中心登录。


上图可以看到,用户请求mail.qiandu.com,然后返回给他一个网址,状态302重定向,service参数就是回来的地址。

标号15:浏览器根据14返回的地址,发起重定向,因为之前访问过一次了,因此这次会携带上次返回的Cookie:TGC到认证中心。

标号16:认证中心收到请求,发现TGC对应了一个TGT,于是用TGT签发一个ST,并且返回给浏览器,让他重定向到mail.qiandu.com


可以发现请求的时候是携带Cookie:CASTGC的,响应的就是一个地址加上TGT签发的ST也就是ticket。

标号17:浏览器根据16返回的网址发起重定向。

标号18:mail.qiandu.com获取ticket去认证中心验证是否有效。

标号19:认证成功,返回在mail.qiandu.com的session中设置登录状态,下次就直接登录。

标号20:认证成功之后就反正用想要访问的资源了。


Demo演示

配置filter

 我们需要在应用的web.xml文件中配置四个Filter,这四个Filter必须按照固定的顺序来进行配置,而且它们必须配置在应用的其它Filter之前。它们的先后顺序要求如下:

1、AuthenticationFilter

casServerLoginUrl用来指定Cas Server登录地址,serverName或service用来指定认证成功后需要跳转地址。

2、TicketValidationFilter

      请求通过AuthenticationFilter的认证之后,如果请求中携带了参数ticket则将会由TicketValidationFilter来对携带的ticket进行校验。 TicketValidationFilter只是对验证ticket的这一类Filter的统称,其并不对应Cas Client中的一个具体类型。Cas Client中有多种验证ticket的Filter,

都继承自AbstractTicketValidationFilter,它们的验证逻辑都是一致的,都有AbstractTicketValidationFilter实现,不同的是使用的TicketValidator不一样。这里我们使用Cas10TicketValidationFilter,也可以使用Cas20ProxyReceivingTicketValidationFilter或Saml11TicketValidationFilter。

3、HttpServletRequestWrapperFilter

 HttpServletRequestWrapperFilter用于将每一个请求对应的HttpServletRequest封装为其内部定义的CasHttpServletRequestWrapper,该封装类将利用之前保存在Session或request中的Assertion对象重写HttpServletRequest的getUserPrincipal()、getRemoteUser()和isUserInRole()方法。

      这样在我们的应用中就可以非常方便的从HttpServletRequest中获取到用户的相关信息

4、AssertionThreadLocalFilter

AssertionThreadLocalFilter可以在应用的其它地方获取Assertion对象,找个过滤器会把Assertion对象存放到当前的线程变量中,我们在程序的任何地方都可以从线程变量中获取当前Assertion,就不需要再从Session或request中进行解析了。这个线程变量是由AssertionHolder持有的,我们在获取当前的        Assertion时也只需要通过AssertionHolder的getAssertion()方法获取即可

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 主要介绍CAS SSO的认证流程。有关这方面的内容再网上也有很多资料,写这篇总结目的一来是自己在理解这块内容的时候...
    spilledyear阅读 9,757评论 1 17
  • 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cook...
    leo0oel阅读 592评论 0 2
  • 基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中,之后访问网站时在过滤器(filter...
    lbyang阅读 2,780评论 0 4
  • 1. CAS 简介 1.1. What is CAS ? CAS ( Central Authenti...
    人在码途阅读 9,712评论 3 51
  • 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中...
    garyond阅读 1,032评论 0 3