参考链接:
https://www.zhihu.com/question/50954473/answer/2496466075
https://blog.51cto.com/u_1472521/4995770
关键流程摘录
第一篇中关键部分如下:
详细流程为:
①用户向网关请求登录或者通过网关请求资源服务器的资源。
②网关发现用户没有授权发起基于 OAuth2 授权码的 OIDC 流程,向授权服务器 Id Server 发起授权请求。
③授权服务器 Id Server 收到授权请求重定向到用户登录页面要求用户登录认证,以发起授权。
④用户输入用户名密码进行登录认证。
⑤Id Server 授权服务器处理用户认证并重定向到网关约定的 OAuth2 Redirect URI,这个过程属于标准的 OIDC 授权码流程。
⑥网关获得 AccessToken 和 IdToken:
如果最初发起的是登录就重定向到/。
如果最初发起的是请求资源服务器资源就令牌中继重定向到对应的资源。
资源服务器通过⑦⑧两个链路响应用户的请求。
请注意,上述流程中生成的 AccessToken 和 IdToken 不允许提供给用户侧,否则会引起中间人攻击,默认提供的是一个 cookie 策略,大部分情况下这种策略是够用的
第二篇中的内容:
场景:源码下载后,服务都启动后,然后浏览器从访问 http://localhost:8080/index 到需要登录,等会成功后然后跳回来并成功显示 /index 页面的内容,这个整个处理过程。
1、访问客户端服务的一个需要登录认证才可以访问的接口,例如 /index
2、判断发现用户没有登录状态,于是乎应该跳转到客户端服务登录页面。在客户端 SecurityConfig 类的 HttpSecurity 中配置了登录页url为 /oauth2/authorization/messaging-client-oidc ,这个url最后一段的值很重要,应该是你客户端服务配置文件中 spring.security.oauth2.client.registration 集合配置中的其中之一,这个登录页的最后一个值 registrationId 表示登录后自动走的授权模式。
3、浏览器开始跳转配置的登录页面 /oauth2/authorization/messaging-client-oidc,这个URL会被 OAuth2AuthorizationRequestRedirectFilter 过滤器拦截(拦截规则为 /oauth2/authorization/*),并解析出 registrationId = messaging-client-oidc
5、oauth2的server收到/oauth2/authorize请求后,先判断server本身是否存在用户已经登录的会话,如果不存在则跳转到server的login页面http://auth-server:9000/login。如果存在已经登录的会话用户,则进行下面的第7步。
6、用户在浏览器输入账号密码进行登录操作。
7、登录成功后,跳转回客户端的redirect_uri,并携带参数code和state,其中code由服务的颁发的有效期较短,state为客户端跳转授权时携带的这里server端原样返回(例如:http://localhost:8080/login/oauth2/code/messaging-client-oidc?code=sc02-aIAimsjl6ayr297VmFIaDWoVi4_1BYW9VgdHsL23S4ZEqLfX9DFPjCNubmFgOMdVN0oxb5SJxSdq4HUVswz3J4cZIVWUFd26p5noO04g1ItkVLNC18Y9MrXDAWC&state=qAs4Ac27tOlvP0i8A1eA3cpbdIx5DPUgPGGV2PZJ75w%3D)
8、客户端接收/login/oauth2/code/messaging-client-oidc请求,被 OAuth2LoginAuthenticationFilter 拦截处理(校验URL是否匹配+参数是否包含code和state),通过拿到的code调用auth-server/auth2/token接口获得access_token、refresh_token和id_token(只有openid授权模式才会返回id_token,其中包含了用户ID等信息,是一个按一定规则进行分割加密的字符串。相关资料:http://www.voidcn.com/article/p-osloewbk-bsq.html)。
9、OAuth2LoginAuthenticationFilter(OAuth2LoginAuthenticationFilter是openid处理过滤器、OAuth2AuthorizationCodeGrantFilter是code模式授权处理过滤器)进行一系列处理后,在最后通过authorizedClientRepository.saveAuthorizedClient保存认证通过的用户信息(默认是存入session中,实际业务一般需要扩展实现存入数据库的表中)。
10、OAuth2LoginAuthenticationFilter父类的doFilter最后通过successfulAuthentication方法进入后续处理,由SavedRequestAwareAuthenticationSuccessHandler中的方法onAuthenticationSuccess处理进行最后的重定向跳转工作,最后进行sendRedirect重定向到我们授权之前访问的地址(在授权访问之前预访问的地址被存入session中,这里在从session中取出来进行重定向)。
11、浏览器加载授权之前访问的url地址,重新进入第1步流程,此时会话中已经存在用户信息,所以通过验证正常调用接口返回了数据。
12、整个oauth2的授权跳转过程结束。
理解
将上面两篇内容结合可以更好的理解,如下是第一篇和第二篇流程之间的对应关系
第一篇 | 第二篇 | |
---|---|---|
① | 1 | |
② | 2 3 4 | |
③ | 5 | |
④ | 6 | |
⑤ | 7 8 9 10 | |
⑥⑦⑧ | 11 |