【SpringSecurity】十六、OAuth2.0授权服务器、资源服务器的配置(理论部分)

news2024/11/15 3:45:36

文章目录

  • 0、OAuth2服务端结构
  • 1、授权服务配置
  • 2、授权服务器 ⇒ 配置客户端详情
  • 3、授权服务器 ⇒ 管理令牌配置
  • 4、授权服务器:配置端点访问的安全约束
  • 5、资源服务器配置

相关📕: 【OAuth2授权服务器配置完整Demo】

0、OAuth2服务端结构

OAuth2服务的提供端,包括两部分:

  • 授权服务:负责校验接入的客户端、登录的用户账户是否合法,以及颁发token
  • 资源服务:校验token,返回资源信息

在这里插入图片描述
比如创建两个服务,uua服务用来做授权服务,order服务用来做资源服务。

1、授权服务配置

Spring Security Oauth核心依赖:

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.4.1</version>
</dependency>

用 @EnableAuthorizationServer 注解并继承AuthorizationServerConfigurerAdapter来配置OAuth2.0 授权服务器。

或者直接去实现AuthorizationServerConfigurer接口都一样

@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
	//略...
}

在这里插入图片描述

授权服务器中,需要配置以下三点:

  • ClientDetailsServiceConfigurer:用来配置客户端详情服务,看支持哪些客户端来请求

  • AuthorizationServerEndpointsConfigurer:解决两点:客户端来申请令牌了,申请的地址是什么(令牌端点)以及令牌怎么发放

  • AuthorizationServerSecurityConfigurer:配置令牌端点的安全约束,哪些url开放,哪些需要鉴权

2、授权服务器 ⇒ 配置客户端详情

通过ClientDetailsServiceConfigurer来配置客户端详情。而一个ClientDetails对象则是表示一个客户端的详情,包括客户端的ID、密码、授权范围、授权类型等。相关属性:

  • clientId:客户端ID
  • secret:客户端密钥
  • scope:限制客户端的访问范围
  • authorizedGrantTypes:授权类型
  • authorities:客户端可以使用的权限

配置客户端详情可以通过内存和数据库的方式:

方式一:

客户端详情ClientDetails的查询要通过ClientDetailsService,可以直接用框架的JdbcClientDetailsService。也可自己实现ClientDetailsService接口和ClientRegistrationService接口的类,用于加载和增删改客户端详情信息。然后如下设置客户端详情服务

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
	clients.withClientDetails(clientDetailsService)
	//...

JdbcClientDetailsService相关源码:

在这里插入图片描述

方式二:

在内存中配置客户端详情服务,硬编码或者使用配置文件+@Value读取实现写活。如下:

/**
 * Oauth2.0客户端角色的信息来源:内存、数据库
 * 这里用内存做测试
 */
@Override
public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception {
    clientDetailsServiceConfigurer.inMemory() //使用内存
            .withClient("c1")  //client_id
            .secret(new BCryptPasswordEncoder().encode("123321"))   //客户端密钥
            .resourceIds("res1","res2")  //资源列表,一个标识,后面配置资源服务会用到
            .authorizedGrantTypes("authorization_code",
                    "password", "client_credentials", "implicit", "refresh_token")  //支持的授权模式,这里即四种都支持
            .scopes("all")  //允许授权的范围,一个标识
            .autoApprove(false)  //不自动授权,即跳转到授权页面,让用户授权
            .redirectUris("http://your_url");  //验证回调地址,授权码通过302重定向方法,这里要验证回调地址是否被恶意篡改
    //后面继续链式调用and方法可以配置第二个客户端的信息

}

通过以上配置,Spring Security将会在内存中或者数据库中加载客户端详情,并在认证和授权过程中使用这些信息来验证和授权客户端的请求。

3、授权服务器 ⇒ 管理令牌配置

AuthorizationServerTokenServices接口定义了令牌操作方法:

在这里插入图片描述

其实现类是DefaultTokenServices:

在这里插入图片描述

该实现类聚合了TokenStore接口,做持久化令牌(令牌存储策略)。其实现类:

在这里插入图片描述

  • InMemoryTokenStore:令牌存内存中
  • JdbcTokenStore:令牌写进数据库
  • JwtTokenStore:JWT令牌,服务端自行解析

以下演示内存中的,先定义TokenStore:

@Configuration
public class TokenConfig {

	//令牌存储策略
	@Bean
	public TokenStore tokenStore() {
		//放内存
		return new InMemoryTokenStore();
	}
}

定义AuthorizationServerTokenServices,使用其实现类DefaultTokenServices,这里设置token的相关配置:

//注入上面定义的令牌存储策略的Bean
@Autowired
private TokenStore tokenStore;

//注入客户端详情服务(定义下这个Bean,是实现方式:JDBC、内存、自己实现这个接口)
@Autowired
private ClientDetailsService clientDetailsService;


//token令牌管理
@Bean
public AuthorizationServerTokenServices tokenServices() {
    DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setClientDetailsService(clientDetailsService);   //客户端信息服务,即向哪个客户端颁发令牌
    tokenServices.setSupportRefreshToken(true);  //支持产生刷新令牌
    tokenServices.setTokenStore(tokenStore);   //令牌的存储策略
    tokenServices.setAccessTokenValiditySeconds(7200);    //令牌默认有效期2小时
    tokenServices.setRefreshTokenValiditySeconds(259200);  //refresh_token默认有效期三天
    return tokenServices;
}

定义好这令牌存储和令牌配置的两个Bean,下面重写第二个configure方法:

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    //你的逻辑
}

这个方法AuthorizationServerEndpointsConfigurer类型的形参,可以配置授权服务器支持的授权类型

  • authenticationManager:配置认证管理器,以支持密码模式
  • userDetailsService:配置这个说明有自己的UserDetailsService接口实现,此后refresh_token获取新令牌,框架会去检查当前账户是否有效(如是否被禁用)
  • authorizationCodeServices:配置授权码服务,以支持授权码模式
  • implicitGrantService:隐式授权模式需要
  • tokenGranter:配置这个,说明要自定义授权逻辑

示例:

/**
 * 授权信息保存策略
 */
@Bean
public ApprovalStore approvalStore(){
    return new InMemoryApprovalStore();
}

//AuthenticationManager对象在Oauth2认证服务中要使用,提取放到IOC容器中,实现WebSecurityConfigurerAdapter的安全配置类中配置
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

//设置授权码模式下,授权码如何存储
@Bean(name = "jdbcAuthorizationCodeServices")
public AuthorizationCodeServices authorizationCodeServices(){
    return new InMemoryAuthorizationCodeServices();
}

/**
 * 令牌端点访问和令牌服务(令牌怎么生成、怎么存储等)
 */
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.authenticationManager(authenticationManager)  //设置认证管理器,密码模式需要
            .authorizationCodeServices(authorizationCodeServices)  //授权码模式需要
            .approvalStore(approvalStore)
            .tokenServices(tokenServices())  //token管理服务
            .allowedTokenEndpointRequestMethods(HttpMethod.POST);  //允许Post方式访问
}

最后,配置授权端点的URL,框架默认URL为:

/oauth/authorize:授权端点

/oauth/token:令牌端点

/oauth/confirm_access:用户确认授权提交端点

/oauth/error:授权服务错误信息端点

/oauth/check_token:用于资源服务访问的令牌解析端点

/oauth/token_key:提供公有密匙的端点,如果你使用JWT令牌的话

AuthorizationServerEndpointsConfigurer的pathMapping方法可以把这些默认的URL替换成自己定义的URL,形参1为默认链接,形参2为新的自定义的URL链接

4、授权服务器:配置端点访问的安全约束

在这里配置框架提供的端点(url),哪些是可以对外公开的,比如下面即check/token接口对外公开

/**
 * token令牌端点访问的安全策略
 * (不是所有人都可以来访问框架提供的这些令牌端点的)
 */
@Override
public void configure(AuthorizationServerSecurityConfigurer authorizationServerSecurityConfigurer) throws Exception {
    authorizationServerSecurityConfigurer.tokenKeyAccess("permitAll()")   //oauth/token_key这个端点(url)是公开的,不用登录可调
            .checkTokenAccess("permitAll()")   // oauth/check_token这个端点是公开的
            .allowFormAuthenticationForClients();  //允许客户端表单认证,申请令牌
}

5、资源服务器配置

Spring Security Oauth核心依赖:

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.4.1</version>
</dependency>

在资源服务做token校验,合法且权限匹配,则返回数据资源。配置方式:

用 @EnableResourceServer注解并继承 ResourceServerConfigurerAdapter(或实现ResourceServerConfigurer)来配置OAuth2.0 授权服务器。

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true)
public class OAuthSourceConfig extends ResourceServerConfigurerAdapter {

    public static final String RESOURCE_ID = "res1";

    @Resource
    ResourceServerTokenServices resourceServerTokenServices;

    @Bean
	public TokenStore tokenStore() {
		//放内存
		return new InMemoryTokenStore();
	}


    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID)   //资源id
                .tokenStore(tokenStore())   //告诉资源服务token在库里
                .tokenServices(resourceServerTokenServices)
                .stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //这就是给客户端发token时的scope,这里会校验scope标识
                .antMatchers("/**").access("#oauth2.hasAnyScope('all')")
                .and()
                .csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

通过ResourceServerSecurityConfigurer对象配置:

  • resourceId:资源ID,对应授权服务器里的资源ID标识
  • tokenServices:ResourceServerTokenServices 类的实例
  • tokenStore:指定令牌在哪儿,如何访问

关于ResourceServerTokenServices,其用来验证token。如何授权服务和资源服务在一个应用上,可用DefaultTokenServices,使用/oauth/check_token这个端点去校验令牌。反之需要使用远程token服务RemoteTokenServices,指定授权服务器校验token的地址。以及自己的密钥和客户端ID:

@Configuration
public class BeanConfig {

    @Bean
    public ResourceServerTokenServices tokenServices() {
        RemoteTokenServices services = new RemoteTokenServices();
        services.setCheckTokenEndpointUrl("http://localhost:9009/oauth/check_token");
        services.setClientId("c1");
        services.setClientSecret("123");
        return services;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1534946.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序分销返佣模式--小程序1-3级分销插件--小程序分销--

团购小程序是一种基于社区团购模式的电商平台&#xff0c;主要面向社区居民用户。 如果你想要开发一款分销团购小程序可以参考以下功能需求进行开发制作。 1、用户注册和登录 提供用户注册和登录功能&#xff0c;使用户能够创建和管理他们的账户。 2、会员管理 包括会员注…

sentinel使用控制台实现

1、添加依赖 <!--整合控制台--><dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-transport-simple-http</artifactId> <version>1.8.0</version></dependency> 此项方法&#xff0…

【RPG Maker MV 仿新仙剑 战斗场景UI (六)】

RPG Maker MV 仿新仙剑 战斗场景UI 六 法术战斗窗口代码仿新仙剑效果 法术战斗窗口 这次来水点内容 由于之前已经做过了仿新仙剑的法术及物品窗口因此本次两篇内容&#xff0c;就来水点内容&#xff01;&#xff01;&#xff01; 由于帮助窗口之前已经做过&#xff0c;因此直接…

uniApp中使用小程序XR-Frame创建3D场景(1)环境搭建

1.XR-Frame简介 XR-Frame作为微信小程序官方推出的3D框架&#xff0c;是目前所有小程序平台中3D效果最好的一个&#xff0c;由于其本身针对微信小程序做了优化&#xff0c;在性能方面比其他第三方库都要高很多。 2.与Three.js的区别 做3D小程序的同学们对Three.js一定不陌生…

蓝桥杯STM32 G431 hal库开发速成——输入捕获

蓝桥杯的输入捕获较为简单&#xff0c;基本不涉及溢出的问题。所以这里就不介绍溢出了。文末有源码。 一、Cubemx配置 二、代码编写 1.在捕获回调函数中 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if(htim->InstanceTIM3){switch(count){case 1:{jishu1…

Mysql数据库的SQL语言详解

目录 一、数据库的基础操作 1、数据库的基本查看和切换 1.1 查看数据库信息 1.2 切换数据库 1.3 查看数据库中的表信息 1.4 查看数据库或数据库中表的结构&#xff08;字段&#xff09; 1.5 数据类型 1.5.1 整数型 1.5.2 浮点型(float和double) 1.5.3 定点数 1.5.4…

鸿蒙一次开发,多端部署(五)页面开发的一多能力介绍

本章介绍如何使用方舟开发框架“一多”能力&#xff0c;开发出在多设备上正常显示的页面。方舟开发框架推荐开发者使用声明式开发范式开发应用&#xff0c;故本章的内容和示例都主要基于声明式开发范式。本章主要包含如下内容&#xff1a; 布局能力 布局决定了页面中的元素按照…

Day75:WEB攻防-验证码安全篇接口滥用识别插件复用绕过宏命令填入滑块类

目录 图片验证码-识别插件-登录爆破&接口枚举 登录爆破 接口枚举 图片验证码-重复使用-某APP短信接口滥用 滑块验证码-宏命令-某Token&Sign&滑块案例 知识点&#xff1a; 1、验证码简单机制-验证码过于简单可爆破 2、验证码重复使用-验证码验证机制可绕过 3、…

九、C#桶排序算法

简介 桶排序是一种线性时间复杂度的排序算法&#xff0c;它将待排序的数据分到有限数量的桶中&#xff0c;每个桶再进行单独排序&#xff0c;最后将所有桶中的数据按顺序依次取出&#xff0c;即可得到排序结果。 实现原理 首先根据待排序数据&#xff0c;确定需要的桶的数量。…

pycharm中的Mark Directory As 里的 Sources Root、Excluded...

这里主要提到两个文件夹的作用&#xff0c;分别是Sources Root、Excluded 1、Sources Root 1、场景 平时使用pycharm&#xff0c;有时出现导包问题&#xff0c;将那个目录Mark Directory as sources root&#xff0c;然后就可以正常运行代码了 2、原理 其实主要就是将那个目录…

算法沉淀——贪心算法七(leetcode真题剖析)

算法沉淀——贪心算法七 01.整数替换02.俄罗斯套娃信封问题03.可被三整除的最大和04.距离相等的条形码05.重构字符串 01.整数替换 题目链接&#xff1a;https://leetcode.cn/problems/integer-replacement/ 给定一个正整数 n &#xff0c;你可以做如下操作&#xff1a; 如果…

Svg Flow Editor 原生svg流程图编辑器(三)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;一&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;三&#xff09; 实现对齐辅助线 在 logicFlow 中&#xff0c;辅助线的实现是通…

《云计算:数字时代的引擎》

在数字化时代&#xff0c;云计算技术以其强大的计算能力和灵活的应用方式&#xff0c;成为推动各行各业发展的引擎。本文将围绕云计算的技术进展、技术原理、行业应用案例、面临的挑战与机遇以及未来趋势进行详细探讨。 云计算的技术进展 云计算的技术进展涵盖了多个方面&…

Spring框架本身自带的一些好用的工具类

1 Assert 很多时候&#xff0c;我们需要在代码中做判断&#xff1a;如果不满足条件&#xff0c;则抛异常。 有没有统一的封装呢? 其实Spring给我们提供了Assert类&#xff0c;它表示断言。 1.1 断言参数是否为空 断言参数是否空&#xff0c;如果不满足条件&#xff0c;则…

Day23 集合

Day23 集合 一、含义 集合是Java API所提供的一系列类&#xff0c;可以用于动态存放多个对象 (集合只能存对象)集合与数组的不同在于&#xff0c;集合是大小可变的序列&#xff0c;而且元素类型可以不受限定&#xff0c;只要是引用类型。(集合中不能放基本数据类型&#xff0c…

flutter实现视频播放器,可根据指定视频地址播放、设置声音,进度条拖动,下载等

需要装依赖&#xff1a; gallery_saver: ^2.3.2video_player: ^2.8.3 实现代码 import dart:async; import dart:io;import package:flutter/material.dart; import package:gallery_saver/gallery_saver.dart; import package:path_provider/path_provider.dart; import pac…

前端框架推荐 Arco Design

Arco Design - 企业级产品的完整设计和开发解决方案 预览地址&#xff1a;Arco Design Pro - 开箱即用的中台前端/设计解决方案 一 开发 有vue3、React版本。 文档地址&#xff1a;Arco Design - 企业级产品的完整设计和开发解决方案 还配有对应脚手架&#xff1a;GitHub -…

sonarqube使用指北(二)-如何启动一次完整的本地扫描

一、引言 上一篇文章之后 我们应该已经成功的部署了sonarqube程序,这一篇文章我们就来进行一次简单的本地扫描。 优点: 安全性:你可以在任何你信任的环境下执行扫描工作,而不是依赖外部安全能力即时反馈: 开发者可以在编写代码时获得即时反馈,了解其代码的质量和潜在问题…

【Godot4.2】随机数应用案例 - 制作骰子组件

概述 在学习随机数之后&#xff0c;我们就来用随机数实现骰子。 初期&#xff1a;不要拘泥于形式。只要表现了随机&#xff0c;骰子可以不必做成骰子的样子。刚开始因为技术力的原因&#xff0c;可能无法实现比较真实和动态的骰子效果&#xff0c;但是这并不意为着不可以做出…

MATLAB | R2024a更新了哪些好玩的东西?

Hey 好久不见&#xff0c;大家一看三月中下旬这个时间节点也应该能猜到这篇更新什么内容&#xff0c;没错MATLAB R2024a正式版发布啦啦拉拉&#xff0c;直接来看看有啥我认为比较有意思的更新点吧&#xff1a; 1 极坐标表达式绘制 将会使用使用fpolarplot函数来替换ezpolar&a…