今天就跟大家聊聊有关如何理解基于的OIDC实现单点登录的原理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
不知大家有没有体会,好像看了很多id4(IdentityServer4,下同)的文章,对:
<ul class=">
oidc究竟是个什么蛤蟆?
OAuth3.0和OpenId Connect究竟有啥区别?
id4切确是什么东西?
id4能干些啥?
id4为什么这么设计?
id4各授权流程的区别是啥?
id4的SSO是基于什么原理?
老实说,这些问题我也一懂半懂,还有就是看多了、时间跨度大,有的以为懂了提笔又忘了。这时大佬肯定说:
”谁叫你不去看源码?“
我默默的留下了两行老泪:马上看,马上看。
但是我觉得id4很多新手和我一样都有这困扰,上手门槛确实有的高。诚然看源码是个不错的学习方法,但上来就让新人或使用者看源码,无疑很不利于推广、直接劝退啊,毕竟大部分都是跟我一样的菜逼(对不起拖后腿了)。
SSO,全称Single sign-on :在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。
比如你登录京东后查看我的订单:https://order.jd.com 然后再去查看购物车https://cart.jd.com/cart.action就不需要重新登录。虽然这里顶级域名一致,但其实单点登录并没有此要求。
单点登录,很容易望文生义,以为单点登录就是限制用户只能在一处登录。
下面我们说说我们我们常用的SSO的常用的实现方式。
这种方式比较简单,使用也比较广泛。
比如我有两个系统:a.example.com 和 b.example.com,很简单,只需要搞个 passport.example.com 登录成功后往:example.com 这个顶级域写登录成功的cookie就行了。而后不管你是c.example.com还是d.example.com或是+∞.example.com都只需要验证登录的cookie就行,简单方便。
不过这种实现方式有个比较大的缺陷:
不能跨域,不能跨顶级的域。
我不能说我登录成功后往jd.com域名下写cookie吧。还有就是每个业务域名都要做登录cookie的校验逻辑 ,不过这算小问题。
既然存在问题,就解决问题吧(这实在没办法解决发现问题的人啊)
Central Authentication Service,简称:CAS, 是一个单点登录框架或者说解决方案,开始是由耶鲁大学的一个组织开发,后来归到apereo管理。同时CAS也是开源的,遵循apache 2.0协议,目前代码放在github上:https://github.com/apereo/cas
打开就惊呆了,看到吧,一堆开源项目在用,这logo闪瞎我的钛合金狗眼了
我们看看发生了啥:
站点App1
用户首次访问web App1,App1发现用户未登录,携带目前访问地址302到CAS Server登录页。
CAS Server登录页检查登录Session不存在,返回一个登录页面。
填写账号,点击登录。
CAS Server验证账号信息成功,创建一个Ticket Granting Ticket(TGT),这个TGT就是当前登录用户的session key。同时,创建一个service ticket并携带service ticket key,st key 作为参数跳转回App1。
App1用get发送st key 去CAS Server验证,验证通过后返回登录用户信息。
App1使用返回的登录用户信息构建当前系统的登录状态,并用一个JSESSIONID标记(JSESSIONID是Apache的默认名),并携带这个JSESSIONID重新访问App1。
App1验证JSESSIONID,登录成功,展示登录成功页面。
第二次访问,验证JSESSIONID,直接访问。
站点App2
用户首次访问web App2,App2发现用户未登录,携带目前访问地址302到CAS Server登录页。
CAS Server登录页携带有App1生成的TGT,那么直接做TCT的验证,验证成功不需要登录,创建一个App2的st key,302回App2。
后续和以上的5,6,7,8 补逻辑相同,不赘述。
CAS的流程大概于此,实际的实现可能会复杂一点,可能会遇到各式各样的问题。但有理论支撑,总体实现起来还是简单,可靠有保证的。
下面说说基于Id4的OIDC是怎么做单点登录的。
把官方samples下下来:https://github.com/IdentityServer/IdentityServer4/tree/master/samples
我删掉了其他项目,剩下这两个,一目了然:
配置IdentityServer,Configs添加这么一个客户端:
// sso implicit client
new Client
{
ClientId = "ssoimplicit", //这个client id 跟 MfcImplicit 里面的配置要一致
ClientName = "sso implicit clinet",
AllowedGrantTypes = GrantTypes.Implicit,
RedirectUris = { "http://sso.client.net/signin-oidc"> PostLogoutRedirectUris = { "http://sso.client.net/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email
}
}
ok,我们用下抓包工具观察下登录流程。
sso.client.net是客户端,而登录页在sso.client.net服务端
我们先打开需要登录才可以访问的:http://sso.client.net/Home/Secure
这里302到了授权端点 http://odic.server.net/connect/authorize
这就是步骤1中, 302挑战的授权端点携带的参数。
点击登录,跳转到是否授权页面,这个页面不一定展示,可通过配置Client的RequireConsent=false,跳过这个页面。
可以清楚的看到去到了:
http://odic.server.net/connect/authorize/callback
callback,哦,这是一个登录回调,它干了啥呢,我们仔细看响应:
我们看到id_token带有登录用户的信息:
iss:token发放的服务器地址
aud:clientid
sid:会话信息
kid:当前token的标识符
name:用户名
此外还有比如id_token的发放时间,过期时间,nonce,用户非机密信息等等。还有蓝色部分需要使用客户端公钥验证的签名等等。
这个时候客户端已经拿到登录用户的信息了,这时客户端直接使用登录用户信息,构建当前应用sso.client.net的登录状态即可。
比如下面的这个 Set名为Implicit的Cookie:
单点登出我就不细说了,使用:
//指定登录方案的方式登出
await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
//或者直接
await HttpContext.SignOutAsync();
暴力点删除cookie也可以,不过那只能算是半退出状态吧。
通过对以上一个使用Id4构建的OIDC实现的登录流程来看,OIDC的SSO它完全无光域名的,id4登录成功后,客户端通过使用id_token来构建自身的登录状态,一个client如此,N个皆然。
大家好像感觉这个SSO的实现方式跟前面的CAS流程很像诶,我们再看一遍前面CAS的图,好像是发现了啥不得了的东西。
没错:openid也是基于CAS流程的一个实现(我根据理解猜的 没有证据)。
再多说两句
id4确实是好东西,暂时用不上也要多了解、学习,最好写个博客做个笔记加深下理解。
在理解的基础上不要去背各种Flow有啥区别什么的,知道什么场景下用那种流程就行,也没几个。
看完上述内容,你们对如何理解基于的OIDC实现单点登录的原理有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。