249.Spring Boot+Spring Security:基于URL动态权限:扩展access()的SpEL表达式
Posted SpringBoot
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了249.Spring Boot+Spring Security:基于URL动态权限:扩展access()的SpEL表达式相关的知识,希望对你有一定的参考价值。
说明
(1)JDK版本:1.8
(2)Spring Boot 2.0.6
(3)Spring Security 5.0.9
(4)Spring Data JPA 2.0.11.RELEASE
(5)hibernate5.2.17.Final
(6)mysqlDriver 5.1.47
(7)MySQL 8.0.12
需求缘起
本节通过扩展access()的SpEL表达式实现URL动态权限。
编码思路
通过扩展SpEL表达式主要在配置具体的类和实现的方法,如下示例
.access("@authService.canAccess(request,authentication)");
其中authService是一个类,canAccess是其中的方法:
@Component
public class AuthService {
public boolean canAccess(HttpServletRequest request, Authentication authentication) {
//在这里编写校验代码…
return true;
}
}
一、扩展access()的SpEL表达式
1.1 编写权限校验方法
编写类AuthService:
package com.kfit.config;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import com.kfit.permission.service.PermissionService;
@Component
public class AuthService {
@Autowired
private PermissionService permissionService;
/**
* 1/ 判断是否已经登录了.
* 当未登录的时候
* principal = anonymousUser
* authentication= AnonymousAuthenticationToken
* 当登录之后
* principal = userdetails.User
* authentication = UsernamePasswordAuthenticationToken
*
*
* @param request
* @param authentication [AnonymousAuthenticationToken|UsernamePasswordAuthenticationToken]
* @return
*/
public boolean canAccess(HttpServletRequest request,Authentication authentication) {
System.out.println("AuthService.canAccess()");
boolean b = false;
System.out.println(authentication);
//1/ 判断是否已经登录了,anonymousUser|userdetails.User
Object principal = authentication.getPrincipal();
if(principal == null || "anonymousUser".equals(principal)) {
return b;
}
//这里可以单独把AnonymousAuthenticationToken拿出来校验,也可以将放到roles统一校验,其role为ROLE_ANONYMOUS
if(authentication instanceof AnonymousAuthenticationToken){
//check if this uri can be access by anonymous
//return
}
Map<String,Collection<ConfigAttribute>> map = permissionService.getPermissionMap();
//String uri = request.getRequestURI();
//这种获取方式不好,不支持/user/**的匹配方式。
//Collection<ConfigAttribute> configAttributes = map.get(uri);
Collection<ConfigAttribute> configAttributes = null;
String resUrl;
//URL规则匹配.
AntPathRequestMatcher matcher;
for(Iterator<String> it = map.keySet().iterator();it.hasNext();) {
resUrl = it.next();
matcher = new AntPathRequestMatcher(resUrl);
if(matcher.matches(request)) {
configAttributes = map.get(resUrl);
break;
}
}
if(configAttributes == null || configAttributes.size() ==0) {
return b;
}
ConfigAttribute cfa = null;
String needRole = null;
for(Iterator<ConfigAttribute> it = configAttributes.iterator();it.hasNext();) {
cfa = it.next();
needRole = cfa.getAttribute();
for(GrantedAuthority grantedAuthority:authentication.getAuthorities()) {
if(needRole.equals(grantedAuthority.getAuthority())) {
System.out.println("needRole = "+needRole);
b = true;
break;
}
}
}
return b;
}
}
1.2 配置WebSecurityConfig
在WebSecurityConfig中添加access配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 定义哪些URL需要被保护、哪些不需要被保护
.antMatchers("/login").permitAll()// 设置所有人都可以访问登录页面
.antMatchers("/","/index").permitAll()
.antMatchers("/test/**","/test1/**").permitAll()
.antMatchers("/res/**/*.{js,html}").permitAll()
.anyRequest().access("@authService.canAccess(request,authentication)")
//.anyRequest().authenticated() // 任何请求,登录后可以访问
.and()
.formLogin().loginPage("/login")
;
}
1.3 去掉注解@PreAuthorize
对于HelloController的注解@PreAuthorize的注解可以去掉了:
@GetMapping("/helloAdmin")
//@PreAuthorize("hasAnyRole('admin')")
public String helloAdmin() {
return "Hello,admin";
}
@GetMapping("/helloUser")
//@PreAuthorize("hasAnyRole('admin','normal')")
public String helloUser() {
return "Hello,user";
}
到这里就可以测试下效果了,和之前的结果应该是一样的。
历史文章
我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。
à悟空学院:http://t.cn/Rg3fKJD
学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!
SpringBoot视频:http://t.cn/R3QepWG
Spring Cloud视频:http://t.cn/R3QeRZc
SpringBoot Shiro视频:http://t.cn/R3QDMbh
SpringBoot交流平台:http://t.cn/R3QDhU0
SpringData和JPA视频:http://t.cn/R1pSojf
SpringSecurity5.0视频:http://t.cn/EwlLjHh
Sharding-JDBC分库分表实战:http://t.cn/E4lpD6e
以上是关于249.Spring Boot+Spring Security:基于URL动态权限:扩展access()的SpEL表达式的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot??????????????????Spring boot??????MySql,Mybatis???PageHelper??????