微服务下的SpringSecurity认证端

从三板斧开始微服务下的SpringSecurity开始

一、引入组件包

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

二、创建适配器

AuthorizationServerConfigurerAdapter是一个授权适配器,在这个适配器中有如下几个核心方法:

  • ClientDetailsServiceConfigurer

用来配置客户端详情服务(ClientDetailsService),这里的配置表明不是任何人都可以来授权中心进行授权的,客户端详情信息在这里进行初始化,可以在内存中也可以来自于数据库,根据你自己的需要进行配置;一个ClientDetails标识一个客户端的详情描述,ClientDetails具体的属性如下:

重要属性说明
属性名称说明
clientId是一个唯一标识,用于标识客户
secret客户端的安全码;微信登录就有安全码
scope用来限制客户端的访问范围,如果为空,标识所有范围都可以访问
authrizedGrantTypes可以使用的授权类型(可选值范围:"authorization_code", "password", "client_credentials", "implicit", "refresh_token"),为空标识所有都支持;微信仅支持authorization_code;
authorities客户端可以使用的权限(基于Spring Security Authorities)
redirectUris回调地址,授权服务会往此地址回调推送客户端相关信息

ClientDetails客户端详情可以在运行时进行更新,可以通过访问底层存储介质(例如:JdbcClientDetailsService)或者自己实现ClientRegisterationService接口或者实现ClientDetailsService来进行定制;

  • AuthorizationServerSecurityConfigurer

配置令牌端点的安全约束;此接口包含了关于令牌管理的必要操作;

实现一个AuthorizationServerTokenServices接口需要继承DefaultTokenServices这个类;此类中包含了一些有用的实现,可以使用它来修改令牌的格式和令牌的存储模式;默认情况下,在创建一个令牌的时候,是使用随机值来进行填充的;这个类中完成了令牌管理的几乎所有事情,唯一需要依赖的是Spring容器中的一个TokenStore对象来定制令牌持久化;在Spring中有一个默认的TokenStore实现,即:ImMemoryTokenStore,这个类是将令牌保存到内存中,其他几个TokenStore实现类都可以根据自己的选择进行使用;

ImMemoryTokenStore:基于内存;

JdbcTokenStore:基于JDBC;

JwtTokenStore:基于JWT,这里啰嗦一下,此种类型时经常常用的类型,全称是“Json web Token”;是吧令牌信息全部编码到令牌本身,这样后端不需要维护令牌相关的信息,这是一大优势,当然缺点就是撤销令牌困难;传输占用空间比较大;

  • AuthorizationServerEndpointsConfigurer

用来配置令牌的访问端点和令牌服务;授权类型(Grant Types)有如下几点:

授权类型说明
授权类型说明
authenticationManager认证管理器,如果你选择的是password(资源所有者密码)这个授权类型时,需要指定authenticationManager对象来进行鉴权
userDetailsService用户主体管理服务,在拥有自己UserDetailsService接口的实现,如果设置了这个属性,那么refresh_token刷新令牌的方式授权类型流程中会多一个检查的步骤,来确保是否依然有效
authorizationCodeServices用于authorization_code授权码模式,用来设置授权服务;
implicitGrantService用于设置隐式授权模式的状态;
tokenGranter这个是深度拓展时使用的;一旦设置,授权将会全部交由自己来掌控,会忽略以上几个属性;

 

  1 @Configuration2 @EnableAuthorizationServer3 @EnableConfigurationProperties(value = JwtCaProperties.class)4 public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {5 6     /**7      * 属性描述:注入数据源8      *9      * @date : 2020/4/12 0012 上午 11:5410      */11     private final DataSource dataSource;12 13     /**14      * 属性描述:JWT配置信息15      *16      * @date : 2020/4/12 0012 下午 10:4917      */18     private final JwtCaProperties jwtCaProperties;19 20     /**21      * 属性描述:用户信息处理22      *23      * @date : 2020/4/13 0013 上午 12:1224      */25     private final MyUserDetailServiceImpl myUserDetailServiceImpl;26 27     private final AuthenticationManager authenticationManager;28 29     /**30      * 功能描述:认证中心配置31      *32      * @author : XXSD33      * @date : 2020/4/12 0012 上午 11:5434      */35     public AuthServerConfig(DataSource dataSource, JwtCaProperties jwtCaProperties, MyUserDetailServiceImpl myUserDetailServiceImpl, AuthenticationManager authenticationManager) {36         this.dataSource = dataSource;37         this.jwtCaProperties = jwtCaProperties;38         this.myUserDetailServiceImpl = myUserDetailServiceImpl;39         this.authenticationManager = authenticationManager;40     }41 42     /**43      * 功能描述:配置第三方客户端的授权服务器安全配置44      * <br />45      * 用来配置令牌的端点安全约束46      *47      * @author : XXSD48      * @date : 2020/4/14 0014 下午 8:5549      */50     @Override51     public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {52         //第三方客户端校验token需要带入 clientId 和clientSecret来校验53         security.checkTokenAccess("isAuthenticated()")54                 //来获取我们的tokenKey需要带入clientId,clientSecret55                 .tokenKeyAccess("isAuthenticated()");56         //使用表单认证的方式进行申领令牌57         security.allowFormAuthenticationForClients();58     }59 60     /**61      * 功能描述:配置接入的客户端62      * <br />63      * 用来配置客户端详情(ClientDetailsService),客户端详情杂这里进行初始化,可以把客户端详情信息写死或这通过64      * 数据库来存储详情信息65      *66      * @author : XXSD67      * @date : 2020/4/12 0012 上午 11:4968      */69     @Override70     public void configure(ClientDetailsServiceConfigurer clients) throws Exception {71         /*//使用内存方式72         clients.inMemory()73                 .withClient("这里写客户端的ID")74                 .secret(new BCryptPasswordEncoder().encode("这里放入密码"))75                 .resourceIds("这里是客户端的资源列表")76                 //此客户端可以使用的授权类型77                 .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")78                 .scopes("允许的授权范围;没有什么特殊的意义,就是一个字符串,是自己根据我们后台的服务进行的一个划分而已")79                 //跳转到授权页面,是否显示授权页面;True标识默认用户同意,不显示授权页面80                 .autoApprove(false)81                 .redirectUris("这里写入你自己的回调地址");82                 //如果有更多的,在这里添加and83                 .and()84                 */85         clients.withClientDetails(clientDetails());86     }87 88     /**89      * 功能描述:配置Token信息90      * <br />91      * 用于配置令牌(Token)的访问端点和令牌服务(TokenService)92      *93      * @author : XXSD94      * @date : 2020/4/12 0012 下午 11:2395      */96     @Override97     public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {98 99         /*
100         * AuthorizationServerEndpointsConfigurer对于不同类型的授权类别也需要配置不同的属性
101         * authenticationManager:
102         * 认证管理器,如果你选择的是password(资源所有者密码)这个授权类型时,需要指定authenticationManager对象来进行鉴权
103         * userDetailsService:
104         * 用户主体管理服务,在拥有自己UserDetailsService接口的实现,如果设置了这个属性,那么refresh_token刷新令牌的方式授权类型流程中会多一个检查的步骤,来确保是否依然有效
105         * authorizationCodeServices:
106         * 用于authorization_code授权码模式,用来设置授权服务;
107         * implicitGrantService:
108         * 用于设置隐式授权模式的状态;
109         * tokenGranter:
110         * 这个是深度拓展时使用的;一旦设置,授权将会全部交由自己来掌控,会忽略以上几个属性;
111         * */
112 
113         final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
114         //加入了之后增强器才有效果
115         tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnchaner(), jwtAccessTokenConverter()));
116         /*
117         * OAuth2.0已经默认配置了几个端点:
118         * /oauth/authorize:授权端点;
119         * /oauth/token:令牌端点;
120         * /oauth/confirm_access:用户确认授权提交的端点;
121         * /oauth/error:授权服务错误信息端点;
122         * /oauth/check_token:用于资源服务访问的令牌进行解析的端点;
123         * /oauth/token_key:使用JWT令牌需要用到的提供共有密钥的端点;
124         * */
125         endpoints
126                 //自定义重新定义端点路径
127 //                .pathMapping("")
128                 .tokenStore(tokenStore())
129                 .tokenEnhancer(tokenEnhancerChain)
130                 .userDetailsService(myUserDetailServiceImpl)
131                 //指定令牌管理服务
132 //                .tokenServices(tokenServices())
133                 //限制Token的信息允许提交的模式
134 //                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
135                 .authenticationManager(authenticationManager);
136     }
137 
138     /*private AuthorizationServerTokenServices tokenServices(){
139         final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
140         //客户端详情服务
141         defaultTokenServices.setClientDetailsService(clientDetails());
142         //令牌自动刷新
143         defaultTokenServices.setSupportRefreshToken(true);
144         //令牌存储策略
145         defaultTokenServices.setTokenStore(tokenStore());
146         //令牌默认有效期,当前设置为2小时;单位秒
147         defaultTokenServices.setAccessTokenValiditySeconds(7200);
148         //刷新令牌默认有效期,当前设置为3天;单位秒
149         defaultTokenServices.setRefreshTokenValiditySeconds(259200);
150 
151         return defaultTokenServices;
152     }*/
153 
154     /**
155      * 功能描述:注入基于JWT的自定义Token增强器
156      *
157      * @author : XXSD
158      * @date : 2020/4/12 0012 下午 11:21
159      */
160     @Bean
161     public AuthTokenEnchaner tokenEnchaner() {
162         return new AuthTokenEnchaner();
163     }
164 
165     /**
166      * 功能描述:Token存储控制对象
167      *
168      * @author : XXSD
169      * @date : 2020/4/12 0012 下午 1:01
170      */
171     @Bean
172     public TokenStore tokenStore() {
173         /*
174          * Token有如下几种方式存储:
175          * 1、基于内存:InMemoryTokenStore;
176          * 2、基于数据库:JdbcTokenStore;
177          * 3、基于Redis:RedisTokenStore;
178          * 4、基于JWT:JwtTokenStore
179          * 这里是基于JWT的
180          * */
181         return new JwtTokenStore(jwtAccessTokenConverter());
182     }
183 
184     /**
185      * 功能描述:Token与用户信息之间的转换器
186      *
187      * @author : XXSD
188      * @date : 2020/4/12 0012 下午 1:01
189      */
190     @Bean
191     public JwtAccessTokenConverter jwtAccessTokenConverter() {
192         final JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
193         jwtAccessTokenConverter.setKeyPair(keyPair());
194         return jwtAccessTokenConverter;
195     }
196 
197     /**
198      * 功能描述:注入证书
199      *
200      * @author : XXSD
201      * @date : 2020/4/12 0012 下午 11:22
202      */
203     @Bean
204     public KeyPair keyPair() {
205         KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(jwtCaProperties.getKeyPairName()), jwtCaProperties.getKeyPairSecret().toCharArray());
206         return keyStoreKeyFactory.getKeyPair(jwtCaProperties.getKeyPairAlias(), jwtCaProperties.getKeyPairStoreSecret().toCharArray());
207     }
208 
209     /**
210      * 功能描述:客户端处理服务
211      *
212      * @author : XXSD
213      * @date : 2020/4/12 0012 上午 11:58
214      */
215     @Bean
216     public ClientDetailsService clientDetails() {
217         /*
218         * 如果是使用JDBC的方式进行,那么就需要在数据库中创建一个表
219         * 表的名称为:oauth_client_details
220         * CREATE TABLE `oauth_client_details` (
221             -- 标识客户端的ID;
222             `client_id` varchar(256) CHARACTER SET utf8 NOT NULL,
223             `resource_ids` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
224             -- 客户端安全码;
225             `client_secret` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
226             -- 用来限制客户端的访问范围,如果为空标识客户端拥有全部的访问范围
227             `scope` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
228             -- authrized;此客户端可以使用的授权类型,默认为空(全部可用:authorizaton_code、password、client_credentals、implicit、refresh_token);注:在微信中只支持authoriazton_code这一种
229             `authorized_grant_types` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
230             -- 回调的地址;授权服务会往此地址推送客户端的相关信息
231             `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
232             -- 此客户端可以使用的权限(基于Spring Security authorities)
233             `authorities` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
234             `access_token_validity` int(11) DEFAULT NULL,
235             `refresh_token_validity` int(11) DEFAULT NULL,
236             `additional_information` varchar(4096) CHARACTER SET utf8 DEFAULT NULL,
237             -- 跳转到授权页面,是否跳转到授权同意页面
238             `autoapprove` varchar(256) CHARACTER SET utf8 DEFAULT NULL,
239             PRIMARY KEY (`client_id`)
240             ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
241         * */
242         return new JdbcClientDetailsService(dataSource);
243     }
244 }

三、授权中心配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {/*** 属性描述:认证服务器加载用户信息对象** @date : 2020/4/13 0013 上午 12:16*/private final MyUserDetailServiceImpl myUserDetailServiceImpl;/*** 功能描述:授权中心安全配置** @author : XXSD* @date : 2020/10/10 0010 下午 1:11*/public WebSecurityConfig(MyUserDetailServiceImpl myUserDetailServiceImpl) {this.myUserDetailServiceImpl = myUserDetailServiceImpl;}/*** 功能描述:用于构建用户认证组件,需要传递userDetailsService和密码加密器** @author : XXSD* @date : 2020/4/13 0013 上午 12:15*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailServiceImpl).passwordEncoder(passwordEncoder());}/*** 功能描述:配置安全拦截策略** @author : XXSD* @date : 2021/1/9 0009 下午 6:34*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http//关闭CSRF跨域检查.csrf().disable()
//                .authorizeRequests()
//                //配置其他请求要求登录
//                .anyRequest().authenticated()
//                //设置并行策略
//                .and()
//                // 可以从默认的login页面登录
//                .formLogin();}/*** 设置前台静态资源不拦截*/@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/assets/**", "/css/**", "/images/**");}/*** 功能描述:随机密码加密器** @author : XXSD* @date : 2020/4/13 0013 上午 12:19*/@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}}

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

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

相关文章

【Android Studio】APP练手小项目——切换图片APP

本项目效果&#xff1a; 前言&#xff1a;本项目最终实现生成一个安卓APP软件&#xff0c;点击按钮可实现按钮切换图片。项目包含页面布局、功能实现的逻辑代码以及设置APP图标LOGO和自定义APP名称。 关于Android Studio的下载与安装见我的博文&#xff1a;Android Studio 最新…

Python接口自动化测试的局限性,该如何破局?

Python接口自动化测试在软件质量保证方面具有显著的优势&#xff0c;如提高测试效率、减少人工错误、支持持续集成和回归测试等。然而&#xff0c;它也存在一些局限性&#xff0c;主要包括以下几点&#xff1a; 1. **初始投入成本高**&#xff1a; - 编写自动化测试脚本需要…

nginx upstream负载均衡模块

前言 upstream 与 proxy 搭配使用 配置upstream upstream server_www.xxx.com_backend {server 192.168.1.128:8081 weight1;server 192.168.1.128:8082 weight2; }配置 server server {listen 80;server_name www.xxx.com;...location / {proxy_pass http://server_…

蓝牙信标定位原理

定位原理&#xff1a;蓝牙信标的定位原理是基于RSSI蓝牙信号强度来做定位的。 根据应用场景不同&#xff0c;通过RSSI定位原理可分为两种定位方式 一、存在性定位 这种方式通常要求所需定位的区域安装一个蓝牙信标即可&#xff0c;手持终端扫描蓝牙信标信号&#xff0c;扫描…

huggingface下载太慢的问题

解决问题&#xff1a;huggingface网站模型文件太大&#xff0c;下载太慢 方式&#xff1a; huggingface镜像站网址 使用方法3的python脚本文件内容 import os# 下载模型 os.system(huggingface-cli download --resume-download THUDM/chatglm2-6b --local-dir /home/bennie…

LeetCode[27]移除元素

Description 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中…

linxu 寻找某一个文件所在的绝对路径

目录 1 实现 1 实现 在Linux系统中&#xff0c;你可以使用find命令来寻找某个文件的绝对路径。find命令可以递归地在指定的目录及其子目录中搜索文件&#xff0c;并根据给定的条件进行匹配。 下面是使用find命令来查找文件的示例&#xff1a; find / -name "filename&q…

C++入门【25-C++ 从函数返回指针】

在上一章中&#xff0c;我们已经了解了 C 中如何从函数返回数组&#xff0c;类似地&#xff0c;C 允许您从函数返回指针。为了做到这点&#xff0c;您必须声明一个返回指针的函数&#xff0c;如下所示&#xff1a; int * myFunction() { . . . } 另外&#xff0c;C 不支持在函数…

Linux【C编程】 信号以及信号的处理方式

文章目录 1.什么是信号&#xff1f;1.1信号是内容受限的一种异步通信机制1.2信号由谁发出的&#xff1f;1.3信号由谁处理&#xff0c;如何处理 2.常见的信号3.进程对信号的处理3.1用signal函数处理SIGINT信号3.2使用sigaction 函数 4.alarm 和pause函数4.1 alarm函数详解4.2 pa…

vue element plus 安装

环境支持# Element Plus 可以在支持 ES2018 和 ResizeObserver 的浏览器上运行。 如果您确实需要支持旧版本的浏览器&#xff0c;请自行添加 Babel 和相应的 Polyfill 。 由于 Vue 3 不再支持 IE11&#xff0c;Element Plus 也不再支持 IE 浏览器。 Edge ≥ 79Firefox ≥ 78C…

用通俗易懂的方式讲解:大模型 RAG 在 LangChain 中的应用实战

Retrieval-Augmented Generation&#xff08;RAG&#xff09;是一种强大的技术&#xff0c;能够提高大型语言模型&#xff08;LLM&#xff09;的性能&#xff0c;使其能够从外部知识源中检索信息以生成更准确、具有上下文的回答。 本文将详细介绍 RAG 在 LangChain 中的应用&a…

愤怒的小红帽

欢迎来到程序小院 愤怒的小红帽 玩法&#xff1a;帮助小红帽安全送达老奶奶家&#xff0c;当狼进入靶子以后鼠标对准靶子&#xff0c; 点击鼠标左键&#x1f3f9;&#xff0c;对应的狼就会被射死&#xff0c;然后继续往前冲&#xff0c;快去&#x1f3f9;吧^^。开始游戏https:…

Jmeter压缩包安装

JMeter安装及配置-Mac 本章要点 前置条件命令行安装压缩包安装 在Mac上安装对应的JMeter工具有两种方式&#xff1a;一种直接借助终端命令行brew进行安装&#xff1b;另外一种和Window电脑一样去JMeter官网下载压缩包安装。 JMeter不需要安装&#xff0c;但是JMeter作为java应用…

谭浩强C语言课后习题-入门与顺序结构

第一题&#xff1a;第一个HelloWorld程序 题目描述 学习了输出语句&#xff0c;请参照例题&#xff0c;编写一个程序&#xff0c;输出以下信息&#xff1a; ************************** Hello World! ************************** 注意&#xff1a;Hello与World之间有一个空格…

伺服电机:伺服电机的控制方式(脉冲控制)

脉冲控制是伺服系统最常见的一种控制方式&#xff0c;基本上每家的伺服驱动器都支持脉冲模式。脉冲模式一般用于轴比较少的场合&#xff08;4轴及以下&#xff09;&#xff0c;轴数比较多的话就需要用总线来控制&#xff0c;毕竟伺服控制器的脉冲输入输出口的数量是有限的。 一…

Hive分区表实战 - 单分区字段

文章目录 一、实战概述二、实战步骤&#xff08;一&#xff09;创建图书数据库&#xff08;二&#xff09;创建国别分区的图书表&#xff08;三&#xff09;在本地创建数据文件&#xff08;四&#xff09;按分区加载数据1、加载中文书籍数据到countrycn分区2、加载英文书籍数据…

Vue如何根据某个时间值获取当月的最后一天

工作中会用到日期组件&#xff0c;有时候选择结束日期只需要用户选择年月&#xff0c;然后需要程序自动补全当月的最后一天&#xff0c;生成yyyy-MM-dd的字符串格式传到后端。 // 纯JS实现 let getEndDateFn (value) > { // 形参value值的格式为yyyy-MM-dd或yyyy-MM …

安全技能讲座 - 便携式灭火器 (Portable Fire Extinguishers )

【Transcript 】 火灾随时随地都可能发生&#xff0c;而且毫无征兆。如果您在家中或工作中遇到火灾&#xff0c;便携式灭火器可以帮助您保护自己&#xff0c;并有可能将火灾扼杀在摇篮中。本课程将向您介绍便携式灭火器、其工作原理和使用方法。成功完成本课程后&#xff0c;您…

字节跳动今年的校招薪资。。。

字节跳动校招情况分析 在写完了绝对顶流 华为 和近两年炙手可热的 比亚迪 的校招薪资之后&#xff0c;不少同学点名要看「字节跳动」。 确实&#xff0c;玩归玩&#xff0c;闹归闹&#xff0c;别拿字节开玩笑。 先来看看和公众号读者相关性较高的岗位校待遇&#xff1a; 研发算…

从0到1:免费热门API集合让开发更高效

各种开发常用的好用API接口&#xff0c;含免费次数~ 天气预报查询&#xff1a;查询全国以及全球多个城市的天气&#xff0c;包含15天天气预报查询。天气预警&#xff1a;可以获取指定城市当前生效中的各类天气预警&#xff0c;如寒潮蓝色预警信号&#xff0c;或一次性拉取全国…