Spring Security业务

Spring Security业务

参考链接:https://github.com/BUG9/spring-security

自定义:https://blog.csdn.net/chisuisi5702/article/details/126282074

介绍

1
为了解决微服务多模块划分之下的权限认证和资源管理问题,引入了如下两种解决方案。

资源服务器 :

ResourceService 判断用户是否具有对应接口的访问权限

1
资源服务器验证用户的令牌可以有多种方式,既可以把用户的令牌拿到授权服务器处进行验证,也可以自己验证。只有授权服务器使用非对称加密令牌或者使用对称加密令牌的方式,且资源服务器知道授权服务器用于加密令牌的密钥所对应的公钥时,资源服务器才能自己验证令牌。本示例中,授权服务器使用对称加密令牌的方式加密令牌,资源服务器自己验证令牌。

鉴权服务器 = 认证服务器 + 授权服务器

授权服务器

:分发token,校验用户信息是否正确

1
2
3
4
5
6
7
四种模式grant_type:
authentication code(授权码),
password(密码),
Implicit(简易模式),
client(客户端模块)

授权服务器主要是提供用户认证、授权、颁发令牌等功能,而资源服务器主要是保护用户资源。授权服务器先给合法的用户颁发令牌,用户再使用获得的令牌到资源服务器申请受保护的用户资源,而资源服务器接收到用户的请求后,会先验证用户的令牌,只有令牌合法才会把用户请求的资源返回给用户,否则拒绝返回。

认证服务器:

解析token获取用户权限信息

Spring Cloud 实现接口级权限验证 :权限验证分为 全部接口需要权限验证 和 部分接口需要权限验证

第一种

微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权!-腾讯云开发者社区-腾讯云 (tencent.com)

1
2
3
4
5
6
7
macro:https://cloud.tencent.com/developer/article/1661343

micro-oauth2-auth:通过auth模块进行token分发和权限校验,设置用户的允许请求路径和角色信息到Redis,方便Gateway访问获取
micro-oauth2-gateway:网关统一拦截处理,对于白名单路径进行直接放行,对于需要权限的路径进行路径判断;解析token,这样后面的微服务模块及就不需要再解析token
micro-oauth2-api:api路由,通过校验的请求路由到模块

总结:感觉不好把握,对于api的请求过于集中

第二种*

demo

(3条消息) springSecurity+oauth2实现权限认证系统(资源服务器与授权服务器分离,client信息入库,token存入redis持久化)_KDoo的博客-CSDN博客

1
2
3
4
5
6
7
8
9
资源服务器具体细节 = https://juejin.im/post/5d8b143be51d4577f54a0fe1
资源服务器+微服务模块 = 权限校验 ,
在微服务中整合 资源服务器 @EnableResourceServer@Enableglobalmethodsecurity注解 + 以及在接口上表上注解
@PreAuthorize("principal.equals(#query.getUsername())") / @PreAuthorize("hasRole("amdin")")
/ @PreAuthorize("@beanName.method(param)") = 自定义注解判断
从而实现,在微服务模块进行接口级的权限验证和处理

总结:感觉比较复杂,如果在每个模块都引入验证失败的权限处理,要崩溃。此外,如果自定义注解判断方法,直接下机。
但是,这个东西好像比较细节,适合我实现

资源服务器原理

1
ResouceServerConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.mugua.release.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
* @Description
* @Author lwc
* @Data 2022/8/29 22:26
*/
@Configuration
@EnableResourceServer //开启资源服务器功能
@EnableWebSecurity //开启web访问安全
public class ResourceServerConfiger extends ResourceServerConfigurerAdapter {

// private String sign_key = "imugua20220829"; //jwt签名密钥
private String sign_key = "ee7dcc6cad12f7d7ef9642e680fdbc4d"; //jwt签名密钥


/**
* @Description 该⽅法⽤于定义资源服务器向远程认证服务器发起请求,进⾏token校验
* 等事宜
* @Param resources
* @Return
* @Author lwc
* @Date 22:29
*/
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
/*// 设置当前资源服务的资源id
resources.resourceId("release");
// 定义token服务对象(token校验就应该靠token服务对象)
RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
// 校验端点/接⼝设置
remoteTokenServices.setCheckTokenEndpointUrl("http://localhost:9999/oauth/check_token");
// 携带客户端id和客户端安全码
remoteTokenServices.setClientId("clientmugua");
remoteTokenServices.setClientSecret("zbcxyz");

resources.tokenServices(remoteTokenServices);*/

//使用jwt令牌
resources.resourceId("release").tokenStore(tokenStore()).stateless(true);//无状态设置
}

/**
* @Description 场景:⼀个服务中可能有很多资源(API接⼝)
* * 某⼀些API接⼝,需要先认证,才能访问
* * 某⼀些API接⼝,压根就不需要认证,本来就是对外开放的接⼝
* * 我们就需要对不同特点的接⼝区分对待(在当前configure⽅法中
* 完成),设置是否需要经过认证
* @Param http
* @Return
* @Author lwc
* @Date 22:59
*/
@Override
public void configure(HttpSecurity http) throws Exception{
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and().authorizeRequests()
.antMatchers("/release/**").authenticated() //需要认证
.antMatchers("/demo/**").authenticated() //需要认证
.anyRequest().permitAll(); //其余不需要认证
}

/**
* @Description 该⽅法⽤于创建tokenStore对象(令牌存储对象)
* token以什么形式存储
* @Param
* @Return {@link TokenStore}
* @Author lwc
* @Date 23:14
*/
public TokenStore tokenStore(){
//return new InMemoryTokenStore();
// 使⽤jwt令牌
return new JwtTokenStore(jwtAccessTokenConverter());
}


/**
* @Description * 返回jwt令牌转换器(帮助我们⽣成jwt令牌的)
* * 在这⾥,我们可以把签名密钥传递进去给转换器对象
* @Param
* @Return {@link JwtAccessTokenConverter}
* @Author lwc
* @Date 23:14
*/
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey(sign_key); // 签名密钥
jwtAccessTokenConverter.setVerifier(new MacSigner(sign_key)); // 验证时使⽤的密钥,
// 和签名密钥保持⼀致3.3.5 从数据库加载Oauth2客户端信息
// 创建数据表并初始化数据(表名及字段保持固定)
return jwtAccessTokenConverter;
}
}

RemoteTokenServices

https://blog.csdn.net/qq_38157516/article/details/100665491

image-20230321230114975

1
2
3
4
5
6
7
8
9
10
11
使用过程中,总结问题如下:

1)所有URL访问,无法使用权限认证控制,也就是ResourceServer或WebSecurity配置不起作用;

2)资源服务器与认证服务器不在同一进程(各自分离属于不同服务)情况下,资源服务器无法使用认证服务器进行权限控制;

3)资源服务器application.yml配置资源服务器问题

4)资源服务器不能配置在配置文件中配置资源服务器id

5)使用四种方式获取的token可以使用url后带上access_token或添加Authorization的http头bearer方式向资源服务器发出访问资源请求,但是如果认证服务器也是资源服务器,无法使用像资源服务器一样访问认证服务器;

Spring Security业务
http://example.com/2023/06/01/业务/Spring Security认证流程业务/
作者
where
发布于
2023年6月1日
许可协议