更多内容欢迎访问我的个人 Java 站点:开坑组-Java站
前言
之前我们搭建了一个可以自己定义用户,包含验证码与持久化 Session 的登录模块,接下来我们开始再原有的基础上添加权限控制,让我们能够控制每一个接口的访问权限。
1. 添加 Mock 的权限 Map
添加一些 Mock 的权限数据,在你具体实现的时候,替换为数据库查询即可
package com.example.security.model;
import org.apache.logging.log4j.util.Strings;
import java.util.HashMap;
import java.util.Map;
public class Permission {
public static final Map<String, String> users = new HashMap<String, String>() {
{
put("admin", "123");
put("test", "123");
}};
public static final Map<String, String> userRoles = new HashMap<String, String>() {
{
put("adminRole", "admin");
put("testRole", "test");
}};
public static final Map<String, String> rolePermissions = new HashMap<String, String>() {
{
put("queryPermission", "adminRole");
put("writePermission", "testRole");
}};
public static final Map<String, String> permissionResources = new HashMap<String, String>() {
{
put("/test/hello", "queryPermission");
put("/test/write", "writePermission");
}};
public static String getKeyByValue(Map<String, String> map, String value) {
String matchedKey = Strings.EMPTY;
for (String key : map.keySet()) {
if (map.get(key).equals(value)) {
matchedKey = key;
}
}
return matchedKey;
}
}
2. 添加权限获取来源处理器
Spring Security 中提供了获取权限数据的接口,我们只需要实现接口
FilterInvocationSecurityMetadataSource
中的方法getAttributes()
即可。
package com.example.security.handler;
import com.example.security.model.Permission;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Component
public class FilterInvocationSecurityMetadataSourceHandler implements FilterInvocationSecurityMetadataSource {
@Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
// 用于存储当前请求所需要的权限
List<String> permissions = new ArrayList<>();
//获取请求地址
FilterInvocation invocation = (FilterInvocation) o;
String requestUrl = invocation.getRequest().getRequestURI();
// 模拟数据库,通过请求路径查询所需要的权限
String resource = Permission.permissionResources.get(requestUrl);
if (!StringUtils.isEmpty(resource)) {
permissions.add(resource);
}
// 返回所需的权限
return SecurityConfig.createList(permissions.toArray(new String[0]));
}
@Override
public Collection<ConfigAttribute> getAllConfigAt