点击查看【bilibili】

image.png

  1. POST /auth/oauth2/token?grant_type=password&scope=server HTTP/1.1
  2. Host: pig-gateway:9999
  3. Authorization: Basic dGVzdDp0ZXN0
  4. Content-Type: application/x-www-form-urlencoded
  5. Content-Length: 32
  6. username=admin&password=YehdBPev

⓪ 网关前置处理

网关针对登录流程主要是两个方面

  • 验证码校验 ValidateCodeGatewayFilter.java :::warning 参考资料: 验证码配置开关 :::

  • 前端已加密的密码进行解密 PasswordDecoderFilter.java , 主要就是把如下图的 password 密文转成明文交由 SpringSecurity处理

image.png :::warning 参考资料: 前端登录请求加密流程参考 :::

① 客户端认证处理

image.png

  • 如上图在登录请求中会携带 Basic base64(clientId:clientSecret), 那么首先OAuth2ClientAuthenticationFilter 会通过调用 RegisteredClientRepository (数据库存储) 来判断传入的客户端是否正确

image.png

③ 正式接收登录请求

:::warning OAuth2TokenEndpointFilter 会接收通过上文 OAuth2ClientAuthenticationFilter 客户端认证的请求 ::: image.png

④ 组装认证对象

:::warning AuthenticationConverter 会根据请求中的参数和授权类型组装成对应的授权认证对象 ::: image.png

⑤ 登录认证对象

  1. public class XXXAuthenticationToken extends OAuth2ResourceOwnerBaseAuthenticationToken {
  2. }

image.png

⑥ 授权认证调用

image.png

⑦ 核心认证逻辑

image.png

多用户体系匹配 UserDetailsService


image.png

密码匹配校验

image.png

用户状态校验

pig 生成token (认证)详解 ⭐️ - 图12

⑧ 用户查询逻辑

:::warning 用户查询逻辑的多种实现形式

  • 解耦: 通过feign 查询其他系统获取并组装成 UserDetails
  • 简单: 认证中心直接查询DB 并组装成 UserDetails :::

image.png

⑨ 密码校验逻辑

image.png

image.png

:::warning 默认支持加密方式如下:

{noop}密码明文
{加密特征码}密码密文

PasswordEncoder 会自动根据特征码匹配对应的加密算法,所以上一步⑧ 查询用户对象组装成 UserDetails 需要特殊处理

:::

  1. return new UserDetails(user.getUsername(),"{bcrypt}"+"数据库存储的密文");

⑩ 生成OAuth2AccessToken

image.png

⑪ Token 存储持久化

image.png :::warning 当前SAS 仅支持 JDBC 和内存 ,PIG 扩展支持Redis 实现 ::: image.png

⑫ 登录成功事件处理

:::warning 基于 SpringEvent 事件处理,可以在这里做更多的处理 日志、个性化等处理逻辑 :::

image.png

⑬ 请求结果输出Token

  1. private void sendAccessTokenResponse(HttpServletRequest request, HttpServletResponse response,
  2. Authentication authentication) throws IOException {
  3. OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = (OAuth2AccessTokenAuthenticationToken) authentication;
  4. OAuth2AccessToken accessToken = accessTokenAuthentication.getAccessToken();
  5. OAuth2RefreshToken refreshToken = accessTokenAuthentication.getRefreshToken();
  6. Map<String, Object> additionalParameters = accessTokenAuthentication.getAdditionalParameters();
  7. // 无状态 注意删除 context 上下文的信息
  8. SecurityContextHolder.clearContext();
  9. this.accessTokenHttpResponseConverter.write(accessTokenResponse, null, httpResponse);
  10. }

:::warning 定义具体的输出返回格式等逻辑 ::: image.png

❤ 问题咨询

手势点击蓝字求关注简约风动态引导关注__2022-09-07+23_18_38.gif