spring security oauth2源码解析

2023-11-06

spring security oauth2源码解析

@EnableResourceServer:启用资源服务配置,注入配置:ResourceServerConfiguration

ResourceServerConfiguration:资源服务配置,通过适配器的方式添加额外配置(资源安全配置 和 http安全配置),这些配置会在注入的配置类ResourceServerConfiguration中全部遍历加载进去

public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId("order").stateless(true);  //资源安全配置的额外配置
    //resourceId;资源id,认证token时会校验资源是否匹配
}

public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/order/**").authenticated();  //http安全配置的额外配置
}

ResourceServerSecurityConfigurer(资源安全配置类):

有许多属性配置(ResourceServerTokenServices),配置核心过滤器OAuth2AuthenticationProcessingFilter,携带access_token进行访问会进入过滤器

OAuth2AuthenticationProcessingFilter.doFilter(),OAuth2保护资源的预先认证过滤器。如果与OAuth2AuthenticationManager结合使用,则会从到来的请求之中提取一个OAuth2 token,之后使用OAuth2Authentication来填充Spring Security上下文

  • 通过TokenExtractor分离出请求中包含的token

  • 通过身份认证管理器AuthenticationManager的实现类OAuth2AuthenticationManager认证token

OAuth2AuthenticationManager.authenticate方法,调用了ResourceServerSecurityConfigurer中的tokenService来通过token获取认证信息

    tokenService分为两类接口:
    ResourceServerTokenServices:根据accessToken加载客户端信息、根据accessToken获取完整的访问令牌详细信息
    AuthorizationServerTokenServices:创建token、刷新token、获取token
  • 将身份信息绑定到SecurityContextHolder中(context上下文中)

HttpSecurity(http安全配置):

配置有哪些路径的请求需要认证

@EnableAuthorizationServer:启用认证服务配置,注入配置:AuthorizationServerSecurityConfiguration

AuthorizationServerConfiguration:认证服务配置,通过适配器的方式添加额外配置(),这些配置会在注入的配置类AuthorizationServerSecurityConfiguration中加载进去

public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.allowFormAuthenticationForClients();//主要是让/oauth/token支持client_id以及client_secret作登录认证
}

public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    String finalSecret = "{bcrypt}"+new BCryptPasswordEncoder().encode("123456");
    //配置客户端信息,配置了两个客户端,一个用于password认证一个用于client认证
    clients.inMemory().withClient("client_1")
           .resourceIds("order")
           .authorizedGrantTypes("client_credentials", "refresh_token")
           .scopes("select")
           .authorities("client")
           .secret(finalSecret)
           .and()
           .withClient("client_2")
           .resourceIds("order")
           .authorizedGrantTypes("password", "refresh_token")
           .scopes("select")
           .authorities("client")
           .secret(finalSecret);
}

public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    //配置端点相关信息
    endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory))
             .authenticationManager(authenticationManager)
             .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
}

AuthorizationServerSecurityConfigurer(认证安全配置类):

配置AuthorizationServer安全认证的相关信息,创建ClientCredentialsTokenEndpointFilter核心过滤器,访问/oauth/token之前会进入过滤器

ClientCredentialsTokenEndpointFilter.attemptAuthentication(),访问/oauth/token之前会先进入过滤器,分解出client_id和client_secret

  • 从请求中分离出client_id和client_secret

  • 通过身份认证管理器AuthenticationManager的实现类ProviderManager认证客户端信息

ProviderManager.authenticate()方法,执行了类内部的一系列的AuthenticationProvider对象的authenticate认证方法,而AuthenticationProvider主要实现类是AbstractUserDetailsAuthenticationProvider抽象类的authenticate方法中调用实现类DaoAuthenticationProvider.retrieveUser(),retrieveUser()中调用UserDetailsService.loadUserByUsername()方法加载出用户信息进行认证

  • 认证提供类AuthenticationProvider中的UserDetailsService接口,用来加载用户信息,提供了几种实现类:InMemoryUserDetailManager(存储在内存中)、JdbcUserDetailManager(存储在数据库)

ClientDetailsServiceConfigurer(客户端相关信息配置类):

配置OAuth2的客户端相关信息

AuthorizationServerEndpointsConfigurer(端点信息配置类):

配置AuthorizationServerEndpointsConfigurer端点配置相关类,包括配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory

Token处理端点TokenEndpoint

经过过滤器的前置校验和身份封装之后,进入/oauth/token端口

  • 通过ClientDetailsService.loadClientByClientId()加载出客户端信息

  • 结合请求信息,创建TokenRequest,将TokenRequest传递给TokenGranter颁发token

  • TokenGranter颁发token,返回Oauth2AccessToken(封装了返回token的数据对象)

TokenGranter的设计思路是使用CompositeTokenGranter管理一个List列表,每一种grantType对应一个具体的真正授权者,在debug过程中可以发现CompositeTokenGranter 内部就是在循环调用五种TokenGranter实现类的grant方法,而granter内部则是通过grantType来区分是否是各自的授权类型

    ResourceOwnerPasswordTokenGranter ==> password密码模式
    AuthorizationCodeTokenGranter ==> authorization_code授权码模式
    ClientCredentialsTokenGranter ==> client_credentials客户端模式
    ImplicitTokenGranter ==> implicit简化模式
    RefreshTokenGranter ==>refresh_token 刷新token专用
  • Granter中通过调用AuthorizationServerTokenServices的createAccessToken(创建token)、refreshAccessToken(刷新token)、getAccessToken(获取token)

  • AuthorizationServerTokenServices中,通过调用TokenStore实现对token的操作,调用tokenStore对产生的token和相关信息存储到对应的实现类中,可以是redis,数据库,内存,jwt

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring security oauth2源码解析 的相关文章

随机推荐

  • 什么是IPU?

    在图像识别的SOC中 有一个很重要的单元 IPU Image Processing Unit 图像处理单元 图像处理单元的目标是提供从图像输入 摄像头传感器 电视信号输入等 到显示设备 LCD显示屏 TV输出 外部图像处理单元等 端到端的数
  • 探索OLED拼接屏的特点及在莱山的场景化应用

    涞山oled拼接屏是一种高清晰度的显示屏 由多个oled屏幕拼接而成 它可以用于各种场合 如商业展示 广告宣传 会议演示等 涞山oled拼接屏具有以下特点 1 高清晰度 oled屏幕具有高对比度 高亮度 高色彩饱和度等特点 可以呈现出非常清
  • go-kit grpc调用及中间件封装

    存在问题 grpc 调用问题 通常我们向业务返回会定义如下的结构 code 20000 msg Success data 但是如果我们定义如下的proro grpc的返回值可以在客户端不能直接使用 还需要使用json进行解析 message
  • 计算机网络1:Tcp三次握手和四次挥手

    一 TCP传输的过程 三次握手 1 建立连接并确认连接 三次握手 过程 1 客户端向服务端发出连接请求SYN 1 seq x 等待服务端响应 状态由CLOSED转为SYN SENT 2 服务端做出响应ACK和连接信号SYN 1 seq y
  • linux在dockers安装rides教程

    在Docker中安装Rider是一项非常有用的技能 因为它可以让您在Linux操作系统上进行开发和调试 本文将介绍如何在Docker上安装Rider 步骤1 安装Docker 首先 您需要在Linux操作系统上安装Docker 您可以使用以
  • 清空文件夹下的SVN文件BAT脚本

    清空文件夹下的SVN文件BAT脚本 1 脚本功能 清空文件夹及其子文件下下的所有 svn文件 避免svn提交时冲突 2 脚本内容 echo on color 2f mode con cols 80 lines 25 REM echo 正在清
  • 智能合约相关设计

    1 运行环境 以太坊采用以太坊虚拟机作为智能合约的运行环境 以太坊虚拟机是一个隔离的轻量级虚拟机环境 运行在其中的智能合约代码无法访问本地网络 文件系统或其他进程 对同一个智能合约 查看什么是智能合约 来说 往往需要在多个以太坊虚拟机中同时
  • 详细实现最短路径(迪杰斯特拉算法)

    最短路径 说白了 就是图里从一个顶点到另一个顶点的最小权值之和 今天 小编带大家一起用迪杰斯特拉 Dijkstra 算法实现它吧 目录 一 实现原理 二 代码实现 一 思路 二 代码 一 实现原理 其实 在小编看来 迪杰斯特拉算法与普里姆算
  • ws协议与http协议的异同

    http协议 识别数据内容 与webSocket协议 同 建立在TCP之上 同http一样通过TCP来传输数据 不同 HTTP协议为单向协议 即浏览器只能向服务器请求资源 服务器才能将数据传送给浏览器 而服务器不能主动向浏览器传递数据 分为
  • Selenium及chromedriver安装教程

    文章目录 安装Python环境及Selenium工具包 使用命令行安装 使用Pycharm安装 安装chromedriver驱动 验证 安装Python环境及Selenium工具包 首先 我们需要安装Python环境 安装好了之后需要安装S
  • keras IMDB数据集 LSTM分类

    在keras提供的IMDB数据集中 word被映射为一个大于0的整数 表示该单词出现频率的排名 这样处理的目的是为了方便按照词频过滤单词 其中0用于表示unknown word 载入数据 x train shape 25000 是一个250
  • 如果IBM再给我一次实习机会

    2014年 我拿到了IBM斯图加特R D的实习机会 在连续被索尼和博世拒掉之后 这个实习对我来说弥足珍贵 我学的是通信专业 在这之前与编程相关的活动只有一学期的安卓Lab 还是靠抱队友大腿才及格 在申请时 我的编程能力可以说几乎为0 连我自
  • java: 找不到符号 符号: 类 ResourceVO 位置: 类 com.

    一 java找不到符号 如果你的代码里没有任何问题 但是java报错找不到符号 如下 解决方法
  • 《Pytorch深度学习和图神经网络(卷 2)》学习笔记——第二章

    基于图片内容的处理任务 主要包括目标检测 图片分割两大任务 目标检测 精度相对较高 主要是以检测框的方式 找出图片中目标物体所在坐标 模型运算量相对较小 相对较快 图片分割 精度相对较低 主要是以像素点的集合方式 找出图片中目标物体边缘的具
  • Prometheus 监控之 kafka

    初探 默认情况下 Kafka metrics 所有的 metric 都可以通过 JMX 获取 暴露kafka metrics 支持两种方式 1 在 Kafka Broker 外部 作为一个独立进程 通过 JMX 的 RMI 接口读取数据 这
  • linux:需要注意docker和aws的rds的mysql默认是UTC而不是中国时区

    问题 如题 解决办法 docker参考 mysql时间不对 修改时区 set global time zone 无效 小书生 的博客 CSDN博客 aws参考 https www youtube com watch v B NaqV A1B
  • 数字IC手撕代码--联发科(总线访问仲裁)

    题目描述 当A B两组的信号请求访问某个模块时 为了保证正确的访问 需要对这些信号进行仲裁 请用Verilog实现一个仲裁器 对两组请求信号进行仲后 要求 协议如图所示 请求方发送req request 信号1表示有请求给仲裁器 仲裁器响应
  • es6扩展运算符 (...)

    es6的扩展运算符就是取出参数对象中的所有可遍历属性 拷贝到当前对象之中 let bar a 1 b 2 let baz bar a 1 b 2 实际上是通过Object assign方法实现的 let baz Object assign
  • 【React】路由懒加载 React.lazy()

    React路由懒加载lazy 文章目录 React路由懒加载lazy React lazy 懒加载概念 React lazy 使用 React lazy 懒加载概念 我们在使用网站时 如果不对路由使用懒加载 则会导致刚打开网站就加载全部路由
  • spring security oauth2源码解析

    spring security oauth2源码解析 EnableResourceServer 启用资源服务配置 注入配置 ResourceServerConfiguration ResourceServerConfiguration 资源