SpringSecurity+OAuth2.0 搭建认证中心和资源服务中心

目录

1. OAuth2.0 简介

2. 代码搭建 

2.1 认证中心(8080端口)

2.2 资源服务中心(8081端口)

3. 测试结果


1. OAuth2.0 简介

OAuth 2.0(开放授权 2.0)是一个开放标准,用于授权第三方应用程序访问用户在资源所有者(用户)的帐户上存储的受保护资源,而无需共享用户凭据。OAuth 2.0 主要用于在互联网上安全地委托授权,广泛应用于身份验证和授权场景。

以下是 OAuth 2.0 的核心概念和流程:

  1. 角色:

    • 资源所有者(Resource Owner): 拥有受保护资源的用户。
    • 客户端(Client): 第三方应用程序,希望访问资源所有者的受保护资源。
    • 授权服务器(Authorization Server): 负责验证资源所有者并颁发访问令牌的服务器。
    • 资源服务器(Resource Server): 存储受保护资源的服务器,它可以与授权服务器相同,也可以是不同的服务器。
  2. 授权类型:OAuth2.0协议一共支持 4 种不同的授权模式:

                授权码模式:常见的第三方平台登录功能基本都是使用这种模式。

                简化模式:简化模式是不需要客户端服务器参与,直接在浏览器中向授权服务器申请令牌(token),一般如果网站是纯静态页面则可以采用这种方式。

                密码模式:密码模式是用户把用户名密码直接告诉客户端,客户端使用说这些信息向授权服务器申请令牌(token)。这需要用户对客户端高度信任,例如客户端应用和服务提供商就是同一家公司,自己做前后端分离登录就可以采用这种模式。

        

                客户端模式:客户端模式是指客户端使用自己的名义而不是用户的名义向服务提供者申请授权,严格来说,客户端模式并不能算作 OAuth 协议要解决的问题的一种解决方案,但是,对于开发者而言,在一些前后端分离应用或者为移动端提供的认证授权服务器上使用这种模式还是非常方便的。

2. 代码搭建 

2.1 认证中心(8080端口)

导入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-security</artifactId><version>2.2.5.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId><version>2.2.5.RELEASE</version></dependency></dependencies>

只需要添加两个配置类即可

MyAuthorizationConfig类

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationConfig extends AuthorizationServerConfigurerAdapter {/*** 客户端存储策略,这里使用内存方式,后续可以存储在数据库*/@Autowiredprivate ClientDetailsService clientDetailsService;/*** Security的认证管理器,密码模式需要用到*/@Autowiredprivate AuthenticationManager authenticationManager;/*** 配置令牌访问的安全约束*/@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security//开启/oauth/token_key验证端口权限访问.tokenKeyAccess("permitAll()")//开启/oauth/check_token验证端口认证权限访问.checkTokenAccess("permitAll()")//表示支持 client_id 和 client_secret 做登录认证.allowFormAuthenticationForClients();}//配置客户端@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {//内存模式clients.inMemory()//客户端id.withClient("test")//客户端秘钥.secret(new BCryptPasswordEncoder().encode("123456"))//资源id,唯一,比如订单服务作为一个资源,可以设置多个.resourceIds("order")//授权模式,总共四种,1. authorization_code(授权码模式)、password(密码模式)、client_credentials(客户端模式)、implicit(简化模式)//refresh_token并不是授权模式,.authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")//允许的授权范围,客户端的权限,这里的all只是一种标识,可以自定义,为了后续的资源服务进行权限控制.scopes("all")//false 则跳转到授权页面.autoApprove(false)//授权码模式的回调地址.redirectUris("http://www.baidu.com"); //可以and继续添加客户端}/*** 令牌存储策略*/@Beanpublic TokenStore tokenStore(){return new InMemoryTokenStore();}@Beanpublic AuthorizationServerTokenServices tokenServices() {DefaultTokenServices services = new DefaultTokenServices();//客户端端配置策略services.setClientDetailsService(clientDetailsService);//支持令牌的刷新services.setSupportRefreshToken(true);//令牌服务services.setTokenStore(tokenStore());//access_token的过期时间services.setAccessTokenValiditySeconds(60 * 60 * 2);//refresh_token的过期时间services.setRefreshTokenValiditySeconds(60 * 60 * 24 * 3);return services;}/*** 授权码模式的service,使用授权码模式authorization_code必须注入*/@Beanpublic AuthorizationCodeServices authorizationCodeServices() {//授权码存在内存中return new InMemoryAuthorizationCodeServices();}/*** 配置令牌访问的端点*/@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints//授权码模式所需要的authorizationCodeServices.authorizationCodeServices(authorizationCodeServices())//密码模式所需要的authenticationManager.authenticationManager(authenticationManager)//令牌管理服务,无论哪种模式都需要.tokenServices(tokenServices())//只允许POST提交访问令牌,uri:/oauth/token.allowedTokenEndpointRequestMethods(HttpMethod.POST);}
}

SecurityConfig类

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {/*** 加密算法*/@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception {//todo 允许表单登录http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginProcessingUrl("/login").permitAll().and().csrf().disable();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//从内存中加载用户,实际生产中需要从数据库中加载auth.inMemoryAuthentication().withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("admin");//后面可以跟and连接}/*** AuthenticationManager对象在OAuth2认证服务中要使用,提前放入IOC容器中* Oauth的密码模式需要*/@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}

2.2 资源服务中心(8081端口)

导入依赖和认证中心相同,添加一个配置类ResourceServerConfig

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {/*** 配置令牌校验服务,客户端携带令牌访问资源,作为资源端必须检验令牌的真伪* TODO 使用JWT作为TOKEN则不必远程调用check_token校验*/@Beanpublic RemoteTokenServices tokenServices() {//远程调用授权服务的check_token进行令牌的校验RemoteTokenServices services = new RemoteTokenServices();// /oauth/check_token 这个url是认证中心校验的token的端点services.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");//客户端的唯一idservices.setClientId("test");//客户端的秘钥services.setClientSecret("123456");return services;}/*** 配置资源id和令牌校验服务*/@Overridepublic void configure(ResourceServerSecurityConfigurer resources)  {//配置唯一资源idresources.resourceId("order")//配置令牌校验服务.tokenServices(tokenServices());}/*** 配置security的安全机制*/@Overridepublic void configure(HttpSecurity http) throws Exception {//#oauth2.hasScope()校验客户端的权限,这个all是在客户端中的scopehttp.authorizeRequests().antMatchers("/**").access("#oauth2.hasScope('all')").anyRequest().authenticated();}
}

测试接口

@RestController
public class TestController {@GetMapping("/test")public String hello() {return "hello world";}
}

3. 测试结果

访问http://localhost:8080/oauth/authorize?client_id=test&response_type=code&scope=all&redirect_uri=http://www.baidu.com

登录,账号admin,密码123456,然后获取授权码

获取令牌

 

访问资源中心

 未携带令牌测试结果

携带令牌测试结果

 

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

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

相关文章

【笔记】Helm-3 主题-13 Helm v2迁移到 v3

Helm v2 迁移到 v3 该指南介绍如何将Helm v2迁移到v3.Helm v2需要被安装且在一个或多个集群中管理版本。 Helm 3变化概述 Helm 2 to 3完整的变化列表在FAQ部分。以下是用户在迁移之前应该要注意的一些改变的概述&#xff1a; Helm | Docs 1.移除了Tiller&#xff1a; 1、用…

Leetcode的AC指南 —— 栈与队列:225.用队列实现栈

摘要&#xff1a; **Leetcode的AC指南 —— 栈与队列&#xff1a;225.用队列实现栈 **。题目介绍&#xff1a;请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 …

简单了解AJAX

文章目录 1、什么是AJAX2、AJAX快速入门3、Axios异步框架3.1、Axios 快速入门3.2、Axios 请求方式别名 1、什么是AJAX 概念&#xff1a;AJAX(Asynchronous JavaScript And XML)&#xff1a;异步的 JavaScript 和 XML AJAX作用&#xff1a; 与服务器进行数据交换&#xff1a;通…

图卷积GCN实战基于网络结构图的网络表示学习实战

下面的是数据&#xff1a; from,to,cost 73,5,352.6 5,154,347.2 154,263,392.9 263,56,440.8 56,96,374.6 96,42,378.1 42,58,364.6 58,95,476.8 95,72,480.1 72,271,419.5 271,68,251.1 134,107,344.0 107,130,862.1 130,129,482.5 227,167,1425.7 167,298,415.7 298,209,42…

GPT属于AI,是LLM的一种实现

GPT&#xff08;Generative Pre-trained Transformer&#xff09;作为一种创新的语言模型&#xff0c;既属于人工智能&#xff08;AI&#xff09;的一部分&#xff0c;也是大规模语言模型&#xff08;LLM&#xff09;的一种实现。本文将探讨GPT在AI和LLM领域的重要性和影响。 …

kafka入门(十):副本数据同步

副本 副本&#xff08;Replica&#xff09;&#xff0c;指的是分布式系统对数据和服务提供的一种冗余方式。 Kafka通过多副本机制实现故障自动转移&#xff0c;在Kafka集群中某个broker节点失效的情况下仍然保证服务可用。 失效副本 在ISR集合之外&#xff0c;也就是处于同…

js监听返回当前页面的方法

要监听用户返回当前页面的操作&#xff0c;可以使用JavaScript中的window.onpopstate事件。这个事件会在浏览器的历史记录发生变化时被触发&#xff0c;其中包括用户点击了浏览器的后退按钮或者通过编程方式调用了history.back()方法。 以下是一个简单的示例代码&#xff0c;演…

PG DBA培训25:PostgreSQL性能分析与优化调整

本课程由风哥发布的基于PostgreSQL数据库的系列课程&#xff0c;本课程属于PostgreSQL Performance analysis and adjustment&#xff0c;学完本课程可以掌握PostgreSQL优化概述与优化方案&#xff0c;PostgreSQL操作系统层优化调整与建议&#xff0c;PostgreSQL存储系统层优化…

Unity3D学习之Unity基础——3D数学

文章目录 1. 前言2 Mathf和Math基础2.1 一般用于只计算一次的函数2.1.1 PI Π PI2.1.2 取绝对值 Abs2.1.3 向上取整 CeilToInt2.1.4 向下取整 FloorToInt2.1.5 钳制函数 Clamp2.1.6 获取最大值 Max2.1.7 获取最小值 Min2.1.8 一个数的n次幂 Pow2.1.9 四舍五入 RoundToInt2.1.10…

腾讯云建站教程,三种方式,随意选

腾讯云怎么建站&#xff1f;使用腾讯云搭建网站有三种方式&#xff0c;可以直接购买腾讯云建站服务如网站建设和CloudPages&#xff0c;也可以购买腾讯云服务器&#xff0c;然后使用开源程序搭建网站。腾讯云百科txybk.com分享腾讯云建站教程&#xff1a; 1、网站建设&#xf…

Spring Boot实现统一异常处理的技术解析

引言 在软件开发过程中&#xff0c;异常处理是非常重要的一环。一个好的异常处理机制可以帮助我们更好地定位问题&#xff0c;提高代码的可维护性和稳定性。Spring Boot作为一款轻量级的Java开发框架&#xff0c;提供了一种简单而高效的方式来实现统一异常处理。本文将详细介绍…

springboot 3 + mysql8 + flyway 数据库版本管理

1、flyway flyway官方文档地址&#xff1a;https://documentation.red-gate.com/fd 对于不怎么看文档的我来说&#xff1a; 1&#xff09;flyway是个管理数据库版本的工具&#xff0c;可以对不同环境的sql进行迁移操作。 2&#xff09;优点&#xff1a;初始化、后期数据的管理…

java使用jsch处理软链接判断是否文件夹

前言 这一次主要是碰到一个问题。因为使用jsch去读取文件的时候&#xff0c;有一些文件它是使用软链接制作的一个映射。因为这里面有一个问题。如果它是软链接你就无法判断他到底是文件。还是文件夹&#xff1f;因为他没有提供可以直接读取的方法&#xff0c;用权限信息去判断…

【异常】SecurityException: JCE cannot authenticate the provider BC

升级JDK21出现该异常 JCRCaused by: java.util.jar.JarException: jar:file:/app//service.jar!/BOOT-INF/lib/bcprov-jdk14-138.jar!/ has unsigned entries - org/bouncycastle/LICENSE.class 解决方案 排除 bcprov-jdk14 依赖 可以通过maven插件去查找<dependency>…

Nomogram文献分析:提取数据

前言 今天教大家如何分析Nomogram类型的文章&#xff0c;并使用我们开发的系统零代码提取数据。 系统地址&#xff1a;https://clinicaldata.fun/ 要分析的文章&#xff1a;https://pubmed.ncbi.nlm.nih.gov/36504658/ 。这是一篇典型的mimic-iii数据分析的套路&#xff0c;…

srm-50——攻防世界

可以知道这道题是二类题型&#xff0c;你完成某个事情给你flag 我们输入正确的东西&#xff0c;给“flag” 运行一下可以知道这些关键词 直接关键词在字符串里面 找到运行得到的东西 INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4) {HMODULE Mo…

vue.js js 雪花算法ID生成 vue.js之snowFlake算法

随着前端业务越来越复杂&#xff0c;自定义表单数据量比较大&#xff0c;每条数据的id生成则至关重要。想到前期IOS中实现的雪花算法ID&#xff0c;照着其实现JS版本&#xff0c;供大家学习参考。 一、库的建立引入 在你项目中创建一个snowFlake.js的文件&#xff1a;拷贝以下…

【2020】百度校招Java研发工程师笔试卷(第二批)算法题

贴一下我去年9月份写的博客 三道编程题&#xff0c;一道数学题&#xff0c;两道图论&#xff0c;哎嘿嘿&#xff0c;我就是不会做&#xff0c;哎嘿嘿&#xff0c;哭了。。。 一.最小值 牛牛给度度熊出了一个数学题&#xff0c;牛牛给定数字n,m,k&#xff0c;希望度度熊能找到…

PG DBA培训21:PostgreSQL性能优化之基准测试

本课程由风哥发布的基于PostgreSQL数据库的系列课程&#xff0c;本课程属于PostgreSQL Performance Benchmarking&#xff0c;学完本课程可以掌握PostgreSQL性能基准测试基础知识,基准测试介绍,基准测试相关指标,TPCC基准测试基础,PostgreSQL测试工具介绍,PostgreSQL性能基准测…

java常见集合类的区别

ArrayList和LinkedList之间有什么区别&#xff1f; ArrayList和LinkedList都是Java集合框架中的List接口的实现类&#xff0c;它们在实现方式、性能和适用场景等方面存在一些区别。 底层数据结构&#xff1a;ArrayList是基于动态数组的数据结构&#xff0c;而LinkedList则是基…