当前位置: 首页 > news >正文

Security OAuth2 SSO单点登录源码剖析ing...(二)

文章目录

  • 单点登录简介
  • SSO客户端
    • @EnableOAuth2Sso注解
      • @EnableOAuth2Client注解
      • OAuth2SsoProperties
      • OAuth2SsoDefaultConfiguration
      • OAuth2SsoCustomConfiguration
      • ResourceServerTokenServicesConfiguration
    • 过滤器
      • 过滤器的顺序早已约定FilterComparator
      • 过滤器配置器顺序说明
      • OAuth2ClientContextFilter
      • OAuth2ClientAuthenticationProcessingFilter
  • SSO服务端

Security OAuth2 SSO单点登录源码剖析 - 自己总结

单点登录简介

SSO客户端

@EnableOAuth2Sso注解

@EnableOAuth2Sso是sso客户端的核心注解,它为sso客户端引入了与单点登录相关的配置。

由该注解引入的配置包括:

  • @EnableOAuth2Client、
  • OAuth2SsoProperties、
  • OAuth2SsoDefaultConfiguration、
  • OAuth2SsoCustomConfiguration、
  • ResourceServerTokenServicesConfiguration

@EnableOAuth2Client注解

使用@Import注解引入了OAuth2ClientConfiguration配置,使用@Bean方式定义了OAuth2ClientContextFilter过滤器,嵌入到Web容器中(注意,是Web容器,并不是security的过滤器链中),当后续的过滤器抛出UserRedirectRequiredException这种类型的异常时,就会让用户重定向到认证中心去做登录。那么,就要保证OAuth2ClientContextFilter过滤器一定是要排在FilterChainProxy的前面的,从【OAuth2授权流程和源码解析】的【FilterChainProxy与其它的web的Filter的顺序】章节,可以知道默认的springSecurityFilterChain的排序值为-100,如果要排在它的前面,那么就需要小于-100,我们可以看到在OAuth2AutoConfiguration自动配置类中引入了OAuth2RestOperationsConfiguration配置类,这个配置类中就注入了上面使用@Bean方式定义的OAuth2ClientContextFilter过滤器,并且使用FilterRegistrationBean将它包装并交给spring容器,注意到它设置的order恰好就是:-100-10 = -100,比-100要小,因此,OAuth2ClientContextFilter排在springSecurityFilterChain的前面是没有问题的。

OAuth2SsoProperties

配置前缀为:security.oauth2.sso,可配置就只是:security.oauth2.sso.login-path = /login

当用户未登录时,访问sso客户端资源,如:http://localhost:1111,抛出认证异常或访问拒绝异常而被异常处理器捕捉到该异常,就会将用户重定向到sso客户端的该路径下,如:http://localhost:1111/login,但此时会让OAuth2ClientAuthenticationProcessingFilter认证过滤器满足此路径匹配要求,因为现在没有任何令牌相关的信息,所以就会抛出UserRedirectRequiredException。而这种类型的异常一旦抛出,就会让OAuth2ClientContextFilter这个过滤器捕捉到,这个OAuth2ClientContextFilter过滤器就会让用户去重定向到认证服务器授权页面去授权:http://localhost:1110/oauth/authorize?client_id=c1&redirect_uri=http://localhost:1111/login&response_type=code&state=Z2Io35

但由于当前用户在认证中心未登录,就会又被认证服务器重定向到认证登录页面,当用户登录完成时,按照OAuth2授权码一般的授权逻辑,就会重定向到授权页面,但这里会由于走自动授权模式,因此就直接重定向到了:http://localhost:1111/login?code=cSdvsL&state=M28wuM,此时就携带了code和state,而一旦拿到了code和state,在OAuth2ClientAuthenticationProcessingFilter过滤器中,就可以按照授权码模式的逻辑获取访问令牌,获取用户信息了

OAuth2SsoDefaultConfiguration

OAuth2SsoCustomConfiguration

ResourceServerTokenServicesConfiguration

过滤器

过滤器的顺序早已约定FilterComparator

这在HttpSecurity的performBuild()方法中,就会对filters属性中所添加的所有过滤器进行排序,排序的规则就是使用的是FilterComparator

final class FilterComparator implements Comparator<Filter>, Serializable {private static final int INITIAL_ORDER = 100;private static final int ORDER_STEP = 100;private final Map<String, Integer> filterToOrder = new HashMap<>();FilterComparator() {Step order = new Step(INITIAL_ORDER, ORDER_STEP);put(ChannelProcessingFilter.class, order.next());put(ConcurrentSessionFilter.class, order.next());put(WebAsyncManagerIntegrationFilter.class, order.next());put(SecurityContextPersistenceFilter.class, order.next());put(HeaderWriterFilter.class, order.next());put(CorsFilter.class, order.next());put(CsrfFilter.class, order.next());put(LogoutFilter.class, order.next());filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter", order.next());filterToOrder.put("org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter", order.next());put(X509AuthenticationFilter.class, order.next());put(AbstractPreAuthenticatedProcessingFilter.class, order.next());filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter", order.next());filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter", order.next());filterToOrder.put("org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter", order.next());put(UsernamePasswordAuthenticationFilter.class, order.next());put(ConcurrentSessionFilter.class, order.next());filterToOrder.put("org.springframework.security.openid.OpenIDAuthenticationFilter", order.next());put(DefaultLoginPageGeneratingFilter.class, order.next());put(DefaultLogoutPageGeneratingFilter.class, order.next());put(ConcurrentSessionFilter.class, order.next());put(DigestAuthenticationFilter.class, order.next());filterToOrder.put("org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter", order.next());put(BasicAuthenticationFilter.class, order.next());put(RequestCacheAwareFilter.class, order.next());put(SecurityContextHolderAwareRequestFilter.class, order.next());put(JaasApiIntegrationFilter.class, order.next());put(RememberMeAuthenticationFilter.class, order.next());put(AnonymousAuthenticationFilter.class, order.next());filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter", order.next());put(SessionManagementFilter.class, order.next());put(ExceptionTranslationFilter.class, order.next());put(FilterSecurityInterceptor.class, order.next());put(SwitchUserFilter.class, order.next());}// 排序方法实现public int compare(Filter lhs, Filter rhs) {Integer left = getOrder(lhs.getClass());Integer right = getOrder(rhs.getClass());return left - right;}// ...
}

过滤器配置器顺序说明

OAuth2ClientContextFilter

OAuth2ClientAuthenticationProcessingFilter

SSO服务端

相关文章:

  • 从程序被SQL注入来MyBatis 再谈 #{} 与 ${} 的区别
  • Python pdf2imges -- pdf文件转图片
  • QT:信号与槽
  • WordPress安装memcached提升网站速度
  • Value-Based Reinforcement Learning(2)
  • 2024.5.26.python.exercise
  • pod 之资源限制 与健康检查
  • Vue项目中npm run build 卡住不执行的几种情况(实战版)
  • P2118 [NOIP2014 普及组] 比例简化
  • Spring从零开始学使用系列(四)之@PostConstruct和@PreDestroy注解的使用
  • 化学中的不确定性。
  • 人工智能+量子计算:飞跃现实边界还是科技幻想?
  • java网络:过滤器修改请求头
  • 一、Elasticsearch介绍与部署
  • 【知识拓展】LocalTunnel-高性价比的内网穿透工具(2)
  • [ JavaScript ] 数据结构与算法 —— 链表
  • __proto__ 和 prototype的关系
  • 30秒的PHP代码片段(1)数组 - Array
  • DataBase in Android
  • echarts花样作死的坑
  • flutter的key在widget list的作用以及必要性
  • gf框架之分页模块(五) - 自定义分页
  • HTML中设置input等文本框为不可操作
  • JavaScript 一些 DOM 的知识点
  • JDK9: 集成 Jshell 和 Maven 项目.
  • oschina
  • select2 取值 遍历 设置默认值
  • vue2.0项目引入element-ui
  • vue中实现单选
  • Wamp集成环境 添加PHP的新版本
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 成为一名优秀的Developer的书单
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 我建了一个叫Hello World的项目
  • 用jquery写贪吃蛇
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 从如何停掉 Promise 链说起
  • 树莓派用上kodexplorer也能玩成私有网盘
  • #Linux(帮助手册)
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)ssm高校实验室 毕业设计 800008
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (十六)Flask之蓝图
  • (原)Matlab的svmtrain和svmclassify
  • (转)Mysql的优化设置
  • .bat批处理(六):替换字符串中匹配的子串
  • .chm格式文件如何阅读
  • .NET CLR Hosting 简介
  • .net core 6 集成 elasticsearch 并 使用分词器