
登陆服务 | 四、单点登陆OIDC
之前简单做好了登陆的部分,但是单独一个登陆用处不大,我们希望的是给其他服务提供登陆的能力。
单点登陆
单点登陆 指的是一处登陆,各个系统都可以按条件自动获取到身份信息的过程。常见的SSO过程有OAuth和SAML两大类,OAuth2.0之上又有 OIDC 。
单点登陆的主要目的有两个:
- 用户可以减少登陆次数,提升认证过程的体验。比如说我登陆了Github,那么我就不再需要登陆CircleCI、Gist之类的其他应用,只需要告诉Github说我授权这些应用访问我的数据即可。
- 减小应用授权体系的复杂程度,不需要每个网站都存储一遍密码,不需要每个网站都做一遍登陆的模块。
OIDC
OIDC是一层构建在OAuth2之上的协议,除了OAuth2的认证流以外,额外规定了一些方便应用接入的资源。也有认证方便非常权威的应用认为OAuth2的核心在于访问资源和分享,而OIDC是规定了认证的部分(按我的理解胡乱复述的)。
OIDC的认证过程中有三方:浏览器、认证服务器、应用服务器。应用服务器需要认证时引导浏览器跳转到认证服务,浏览器向认证服务器认证后携带认证code跳转回应用服务器,最后应用服务器向认证服务器验证Code并获取用户信息,将用户信息放入session中完成对应浏览器的认证过程。过程中code是一个普通字符串以外,其他的通信大都依靠JWT的签名来验证发布者身份。
计划在我的登陆服务中集成的就是OIDC的过程。
SAML
和OIDC的验证过程类似,SAML通过XML传递消息,由于过程类似,就不多描述了
Auth
Auth一般可以理解为Authentication,也可以理解成Authorization。之前一直不理解是什么概念是什么区别,一直到工作以后写了第一个OAuth2的应用才理解。
Authentication
Authentication也就是身份认证,证明我是我的过程。比如说密码认证,手机号和短信认证,登陆以后服务器就可以认定这个终端是我在使用。
Authorization
Authorization叫授权,授权什么应用可以使用什么资源。比如说我登陆了QQ,要在一个应用中用到QQ登陆,那么登陆后这个应用可以访问我的哪些数据?只是我的ID吗?还是可以获取我的公开信息,还是可以获取到一部分的不开放的数据,还是可以获取到我的好友列表。类似的还有有的时候是比如说Kubernetes集群这样、授权用户访问某些访问资源,有的时候是用户授权应用访问某些资源。
OIDC
ORY/Hydra
OIDC可以自己全部实现一遍,倒是没有什么大问题,但是考虑耗费精力比较多,没有必要自己造轮子,所以我使用了ORY/Hydra来构建OIDC的部分
Hydra是开源认证服务提供商开发的认证服务,部署一个额外的hydra服务+自己写几个认证和授权的页面就可以实现完整的OIDC服务的功能。
Browser Application Login-Server Hydra
| visit application| | |
+----------------->| | |
| redirect to auth | | |
|<-----------------+ | |
| visit hydra | | |
+------------------+--------------------+-------------------->|
| | | redirect to login |
|<-----------------+--------------------+---------------------+
| visit login service | |
+------------------+------------------->| fetch login info |
| | |-------------------->|
| | redirect to hydra | return login info |
| | after login |<--------------------+
|<-----------------+--------------------+ |
| visit hyra | | |
+------------------+--------------------+-------------------->|
| | |redirect 2 consent |
|<-----------------+--------------------+---------------------+
| visit consent service | |
+------------------+------------------->| fetch consent info |
| | +-------------------->|
| | redirect to hydra | return consent info |
| | after consent |<--------------------+
|<-----------------+--------------------+ |
| visit hydra | | |
+------------------+--------------------+-------------------->|
| | | redirect with code |
|<-----------------+--------------------+---------------------|
| visit app with code | |
+----------------->| fetch token with code |
| +--------------------+-------------------->|
| | | return token |
| <--------------------+---------------------+
| | fetch user info | |
| +------------------->| |
| | return user info | |
| |<-------------------+ |
|return with session | |
|<-----------------+ | |
Hydra在其中维护了Token、Consent和部分Login的状态。
需要实现的部分
认证
由于登陆服务本身就有登陆的功能,也就是所谓的身份认证,我们是不需要处理认证过程的。只需要在没有登陆的情况下跳转到登陆页面,登陆以后跳转回来就行。
授权
授权这一步在OIDC中主要是需要用户授权应用访问用户的某些数据,对于OIDC来说则是需要提供一个Consent Flow,告知用户应用一定要用哪些数据、可选使用哪些数据,这个授权的范围称为是scope,需要实现一个页面来告知用户有哪些scope、选择scope。
登出
无需多言。
资源发现
OIDC同时要求提供资源发现的地址,主要是通过JSON提供了各个资源所在的地址。Hydra中自带。
应用管理
为了方便管理OAuth2应用,我们还需要实现一个OAuth2应用的页面。
具体的代码
具体来说我们就是需要实现三个HTTP Handler,分别处理OIDC的的登陆、授权和登出。
除此之外需要一个只能给管理员或者管理员组查看的面板,用来管理OIDC的应用。