一般的内部管理系统,权限比较复杂,通常权限都是动态配置的,也就是下面我们要讲的的rbac模型
RBAC
详细原理请度娘,这里只是涉及到企业权限的功能级权限,数据级权限还要我们自己控制(用户只能看见它相关的业务表数据)
Spring Security中支持我们自定义的实现,就像这样调用,下面我们来代码实现
config.anyRequest().access("@rbacService.hasPermission(request,authentication)")
权限控制
新建一个authorize项目实现rbac权限,pom文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>tiger-auth</artifactId>
<groupId>com.rui.tiger</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.rui.tiger</groupId>
<artifactId>tiger-auth-authorize</artifactId>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
</dependencies>
</project>
定义rbac接口及实现
package com.rui.tiger.auth.authorize.service;
import org.springframework.security.core.Authentication;
import javax.servlet.http.HttpServletRequest;
/**
* 用户权限判断接口
* @author CaiRui
* @date 2019-05-07 08:02
*/
public interface RbacService {
boolean hasPermission(HttpServletRequest request, Authentication authentication);
}
package com.rui.tiger.auth.authorize.service;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author CaiRui
* @date 2019-05-07 08:05
*/
@Component("rbacService")
public class RbacServiceImpl implements RbacService {
private AntPathMatcher antPathMatcher=new AntPathMatcher();
@Override
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
Object principal = authentication.getPrincipal();
boolean hasPermission = false;
if (principal instanceof UserDetails) {
String username = ((UserDetails) principal).getUsername();
//读取用户所拥有权限的所有URL 这个应该根据用户名从数据库中查询 此处只是模拟
List<String> urls = new ArrayList<>();
for (String url : urls) {
//匹配 /user/* 这种格式
if (antPathMatcher.match(url, request.getRequestURI())) {
hasPermission = true;
break;
}
}
}
return hasPermission;
}
}
demo项目中引入此依赖,并配置
package com.rui.tiger.auth.demo.security;
import com.rui.tiger.auth.core.authorize.AuthorizeConfigProvider;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.stereotype.Component;
/**
* 业务模块权限配置实现
* @author CaiRui
* @date 2019-05-06 12:16
*/
@Component
@Order(Integer.MAX_VALUE)
public class DemoAuthorizeConfigProvider implements AuthorizeConfigProvider {
@Override
public boolean config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
config.antMatchers(
"/user/regist", // 注册请求
"/error",
"/connect/*",
"/auth/*",
"/signin",
"/social/signUp", // app注册跳转服务
"/swagger-ui.html",
"/swagger-ui.html/**",
"/webjars/**",
"/swagger-resources/**",
"/v2/**"
).permitAll();
/*
利用@Order注解实现CommonAuthorizeConfigProvider中的放行路径不需要自定义权限验证
*/
config.anyRequest()
.access("@rbacService.hasPermission(request,authentication)");
return true;
}
}