springboot集成security(鉴权)
Posted 364.99°
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot集成security(鉴权)相关的知识,希望对你有一定的参考价值。
本文承接上一章节内容:springboot集成security(认证)
上一章节: https://blog.csdn.net/m0_54355172/article/details/128239128
1. 授予静态资源访问权限
因为我的演示案例涉及到多个页面,所以先说一下如何给静态资源授予访问权限。
不过首先,我先来讲一下 springboot中无法访问到静态资源的问题的处理方案,这个不涉及security。
1. springboot访问不到静态资源的处理方案
一般,我们会把 .html 和其对应的 静态资源(.css、.js、.png)分开放置:
- .html 放到 /resources/templates/
- 静态资源放到 /resources/static/**
可是,我们会发现,这样放置,在启动项目的时候,根本访问不到静态资源,其解决方案如下:
-
修改启动类:
@MapperScan("com.chenjy.security_demo.mapper") @SpringBootApplication public class SecurityDemoApplication extends WebMvcConfigurationSupport public static void main(String[] args) SpringApplication.run(SecurityDemoApplication.class, args); @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) registry.addResourceHandler("/css/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/css/"); super.addResourceHandlers(registry);
- extends WebMvcConfigurationSupport,重写 addResourceHandlers
- 在方法中增加对 /css 路径的映射。
-
修改html:
<html lang="en" xmlns:th="https://www.thymeleaf.org"> <head> <base th:href="@/"> <meta charset="UTF-8"> <title>登录</title> <link rel="stylesheet" href="../../static/css/login.css" th:href="@/css/login.css"/> </head>
- html 标签的 xmlns:th=“https://www.thymeleaf.org” 引用不能缺少
- 在 head 标签里增加 <base th:href=“@/”> 配置
- 修改 link 标签 <link rel=“stylesheet” href=“…/…/static/css/login.css” th:href=“@/css/login.css”/>
2. 授权访问静态资源
经过上述配置之后,我们如果不使用 security 的话,就能访问到静态资源了,但是当我们使用了 security,那么我们会发现,又访问不到静态资源了。
这是因为,我们没有权限访问静态资源,所以,我们需要授权访问静态资源。
.antMatchers("/**/*.css") // 从根目录开始,授予所有目录下的所有 .css 文件的可访问权限
.permitAll()
2. 权限授予的方法
授权都是基于路径匹配
方法 | 说明 |
---|---|
permitAll | 免登陆访问 一般描述静态资源,css、js、jpg |
anonymous | 登录后不可访问 登录页面和登录请求 |
authenticated | 登录后可访问 |
denyAll | 任意用户任意状态都不可访问 |
fullyAuthenticated | 完整登录才可访问 收支 |
rememberMe | 记住我,一段时间内访问免登陆 |
上面所有方法的底层都是 access ,可以实现任何权限授予逻辑,基于权限表达式的权限授予方法。
权限表达式:
- 定值表达式
access(“permitAll”) 等同于 permitAll() - 动态表达式
3. 权限管理
1. 基于角色的权限管理(role)
role: 权限
user: 用户
role_user:映射
1. 数据库查询
根据用户名查询权限。
-
mapper
<select id="getRoleByName" parameterType="string" resultType="string"> select r.authority from role r, role_user ru where r.id = ru.rid and ru.uid = ( select rid from role_user where uid = ( select id from user where name = #name )) </select>
String getRoleByName(String name);
-
service
String getRoleByName(String name);
@Override public String getRoleByName(String name) return userMapper.getRoleByName(name);
2. UserDetailsServiceImpl权限获取
从数据库获取对应角色的权限,并将权限封装到 UserDetails 中返回。
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
com.chenjy.security_demo.dto.User user = userService.getUserByName(username);
if (user == null)
throw new UsernameNotFoundException("用户名错误");
// 用户登录成功之后,查询用户的权限集合,包括角色和权限
// security 严格要求:角色名的前缀必须是ROLE_,在代码中拼接
// 角色和权限是平等的,都是权限
String auth = "ROLE_" + userService.getRoleByName(username);
System.out.println(username + "的权限是:" + auth);
// 匹配用户密码
// createAuthorityList可以装入一个字符串,也可以多个字符串,也可以直接装入一个字符串数组
User res = new User(username, user.getPassword(), AuthorityUtils.createAuthorityList(auth));
return res;
在 loadUserByUsername 中, security 会等待用户登录成功之后,再去查询用户权限。
注意: security 严格要求:角色名的前缀必须是 ROLE_,但不建议在数据库中直接存入前缀,建议在代码中拼接字符串。
启动项目,登录,查看控制台输出:
3. 配置访问权限
前端代码: https://blog.csdn.net/m0_54355172/article/details/128247732
事先已经写好了两个页面:resource.html——对应接口:/resource、free.html——对应接口:/free
现在需要配置其访问权限:/resource——只有权限为 all 的用户才可以访问,/free——所有用户都可以访问。
.antMatchers("/resource")
.hasRole("all")
.antMatchers("/free")
.hasAnyRole("all", "sim")
演示一下效果:
hasRole(all) 具备 all 权限才能访问匹配到的路径。
hasAnyRole(“all”, “sim”) 具备 all、sim 中任意一个权限就可以访问匹配到的路径。
2. 基于资源的权限管理(authority)
相比于 基于角色的权限管理,基于资源的权限管理 更加细粒度。
hasAuthority(“read,write”)
hasAnyAuthority(“read,write”, “read”)
3. 基于客户端ip的权限管理(IPAddress)
.antMatchers("/free")
.hasIpAddress("127.0.0.1")
注意:ip规则访问要求完整匹配,所以不能填写 localhost 作为ip。
-
按照上述配置,localhost 就不能访问 /free
-
通过打印访问的主机ip,可知道 localhost 的ip 为 0:0:0:0:0:0:0:1
request.getRemoteHost()
修改配置:
.hasIpAddress("0:0:0:0:0:0:0:1")
但是可以发现,localhost 依旧访问不到资源
但是 127.0.0.1 就可以访问。
小结: 别用 localhost 。
未完待续…
以上是关于springboot集成security(鉴权)的主要内容,如果未能解决你的问题,请参考以下文章
前后端分离项目中 springboot 集成 shiro 实现权限控制
spring security oauth2认证中心 集成zuul网关的代码分析