在上一篇中,提到一个类customSecurityMetadataSource,这个类的作用是提供动态权限管理的元数据,也就是读取数据库里的相应数据,整理得到一个权限配置元数据。代码如下
package com.security; import java.util.Collection; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; 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.AntPathMatcher; import com.entity.Menu; import com.repository.MenuRepository; @Component public class CustomSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { @Autowired MenuRepository menuRepository; AntPathMatcher antPathMatcher = new AntPathMatcher(); @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { String requestURI = ((FilterInvocation) object).getRequest().getRequestURI(); List<Menu> allMenu = menuRepository.getAllMenu(); for (Menu menu : allMenu) { if (antPathMatcher.match(menu.getPattern(), requestURI)) { //将List转成数组 String[] roles = menu.getRoles().stream().map(r -> r.getNameEn()).toArray(String[]::new); return SecurityConfig.createList(roles); } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> clazz) { return FilterInvocation.class.isAssignableFrom(clazz); } }
这个类的思路比较简单,就是读出数据库中的所有路径得到一个list,然后遍历list里每个元素,检查是否有与请求路径匹配的元素,如果有则返回该路径对应的可访问角色集。其中将list转为数组的语句较难理解:
String[] roles = menu.getRoles().stream().map(r -> r.getNameEn()).toArray(String[]::new);
stream()方法是获取顺序流,然后用map()方法,将每个role里的英文名读取成的数组拼合成一个新数组返回给数组roles。
前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理(四):自定义动态权限元数据配置类
原文:https://www.cnblogs.com/wwwzgy/p/14817686.html