SpringSecurity 微服务权限方案

本文介绍了微服务的概念,包括其由来、优势和本质,重点探讨了微服务认证与授权的实现思路,使用SpringSecurity进行权限管理。讲解了基于token的授权流程,JWT的组成和签名算法,并概述了SpringSecurity的过滤器链和基本工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么是微服务

1.1微服务由来:
微服务最早由 Martin Fowler 与 James Lewis 于 2014 年共同提出,微服务架构风格是一种使用一套小服务来开发单个应用的方式途径,每个服务运行在自己的进程中,并使用轻量级机制通信,通常是 HTTP API,这些服务基于业务能力构建,并能够通过自动化部署机制来独立部署,这些服务使用不同的编程语言实现,以及不同数据存储技术,并保持最低限度的集中式管理。

1.2微服务优势:
(1)微服务每个模块就相当于一个单独的项目,代码量明显减少,遇到问题也相对来说比较好解决。
(2)微服务每个模块都可以使用不同的存储方式(比如有的用 redis,有的用 mysql等),数据库也是单个模块对应自己的数据库。
(3)微服务每个模块都可以使用不同的开发技术,开发模式更灵活。

1.3微服务本质:
(1)微服务,关键其实不仅仅是微服务本身,而是系统要提供一套基础的架构,这种架构使得微服务可以独立的部署、运行、升级,不仅如此,这个系统架构还让微服务与微服务之间在结构上“松耦合”,而在功能上则表现为一个统一的整体。这种所谓的“统一的整体”表现出来的是统一风格的界面,统一的权限管理,统一的安全策略,统一的上线过程,统一的日志和审计方法,统一的调度方式,统一的访问入口等等。
(2)微服务的目的是有效的拆分应用,实现敏捷开发和部署。

2.微服务认证与授权实现思路

2.1认证授权过程分析:
(1)如果是基于 Session,那么 Spring-security 会对 cookie 里的 sessionid 进行解析,找到服务器存储的 session 信息,然后判断当前用户是否符合请求的要求。
(2)如果是 token,则是解析出 token,然后将当前请求加入到 Spring-security 管理的权限信息中去。

在这里插入图片描述
如果系统的模块众多,每个模块都需要进行授权与认证,所以我们选择基于 token 的形式进行授权与认证,用户根据用户名密码认证成功,然后获取当前用户角色的一系列权限值,并以用户名为 key,权限列表为value 的形式存入 redis 缓存中,根据用户名相关信息生成 token 返回,浏览器将 token 记录到 cookie 中,每次调用 api 接口都默认将 token 携带到 header 请求头中,Spring-security 解析 header 头获取 token 信息,解析 token 获取当前用户名,根据用户名就可以从 redis 中获取权限列表,这样 Spring-security 就能够判断当前请求是否有权限访问。

2.2权限管理数据模型:
在这里插入图片描述
2.3JWT介绍:
1.访问令牌的类型:
在这里插入图片描述
2.JWT组成:
典型的,一个 JWT 看起来如下图:
在这里插入图片描述
该对象为一个很长的字符串,字符之间通过"."分隔符分为三个子串。
每一个子串表示了一个功能块,总共有以下三个部分:JWT 头、有效载荷和签名。

JWT 头
JWT 头部分是一个描述 JWT 元数据的 JSON 对象,通常如下所示。

{
   
	"alg": "HS256",
	"typ": "JWT"
}

在上面的代码中,alg 属性表示签名使用的算法,默认为 HMAC SHA256(写为 HS256);
typ 属性表示令牌的类型,JWT 令牌统一写为 JWT。最后,使用 Base64 URL 算法将上述
JSON 对象转换为字符串保存。

有效载荷
有效载荷部分,是 JWT 的主体内容部分,也是一个 JSON 对象,包含需要传递的数据。 JWT指定七个默认字段供选择。
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID 用于标识该 JWT
除以上默认字段外,我们还可以自定义私有字段,如下例:

{
   
	"sub": "1234567890",
	"name": "Helen",
	"admin": true
}

请注意,默认情况下 JWT 是未加密的,任何人都可以解读其内容,因此不要构建隐私信息
字段,存放保密信息,以防止信息泄露。

JSON 对象也使用 Base64 URL 算法转换为字符串保存。

签名哈希
签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

首先,需要指定一个密码(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为 HMAC SHA256)根据以下公式生成签名。

HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(claims), secret)在计算出签名哈希后,JWT 头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用"."分隔,就构成整个 JWT 对象。

Base64URL 算法
如前所述,JWT 头和有效载荷序列化的算法都用到了 Base64URL。该算法和常见 Base64 算法类似,稍有差别。

作为令牌的 JWT 可以放在 URL 中(例如api.example/?token=xxx)。 Base64 中用的三个字符是"+","/“和”=",由于在 URL 中有特殊含义,因此Base64URL 中对他们做了替换:"=“去掉,”+“用”-“替换,”/“用”_"替换,这就是 Base64URL 算法。

2.4具体代码实现:
在这里插入图片描述
1 编写核心配置类
Spring Security 的核心配置就是继承WebSecurityConfigurerAdapter 并注解**@EnableWebSecurity** 的配置。这个配置指明了用户名密码的处理方式、请求路径、登录登出控制等和安全相关的配置;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {
   
	 //自定义查询数据库用户名密码和权限信息
	 private UserDetailsService userDetailsService;
	 //token 管理工具类(生成 token)
	 private TokenManager tokenManager;
	 //密码管理工具类
	 private DefaultPasswordEncoder defaultPasswordEncoder;
	 //redis 操作工具类
	 private RedisTemplate redisTemplate;
	 @Autowired
	 public TokenWebSecurityConfig(UserDetailsService userDetailsService, 
	 DefaultPasswordEncoder defaultPasswordEncoder,TokenManager tokenManager, RedisTemplate  redisTemplate) {
   
		 this.userDetailsService = userDetailsService;
		 this.defaultPasswordEncoder = defaultPasswordEncoder;
		 this.tokenManager = tokenManager;
		 this.redisTemplate = redisTemplate;
	 }
	 /**
	 * 配置设置
	 */
	 //设置退出的地址和 token,redis 操作地址
	 @Override
	 protected void configure(HttpSecurity http) throws Exception {
   
		 http.exceptionHandling()
		 .authenticationEntryPoint(new UnauthorizedEntryPoint())
		 .and().csrf().disable()
		 .authorizeRequests()
		 .anyRequest().authenticated()
		 .and().logout().logoutUrl("/admin/acl/index/logout")
		 .addLogoutHandler(new 
		 TokenLogoutHandler(tokenManager,redisTemplate)).and()
		 .addFilter(new TokenLoginFilter(authenticationManager(), 
		 tokenManager, redisTemplate))
		 .addFilter(new  TokenAuthenticationFilter(authenticationManager(), tokenManager,  redisTemplate)).httpBasic();
	 }
	 /**
	 * 密码处理
	 */
	 @Override
	 public void configure(AuthenticationManagerBuilder auth) throws Exception {
   
		auth<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值