多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Spring Security动态权限管理 * Spring Security核心配置入口 ~~~ @Configuration @EnableGlobalMethodSecurity(prePostEnabled=true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ... @Autowired private MyFilterSecurityInterceptor myFilterSecurityInterceptor; @Override protected void configure(HttpSecurity http) throws Exception { ... registry.and() ... //添加自定义权限过滤器 .addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class) } } ~~~ * 权限管理过滤器 监控用户行为 ~~~ @Component public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { @Autowired private FilterInvocationSecurityMetadataSource securityMetadataSource; @Autowired public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) { super.setAccessDecisionManager(myAccessDecisionManager); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } public void invoke(FilterInvocation fi) throws IOException, ServletException { InterceptorStatusToken token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } @Override public void destroy() { } @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } } ~~~ * 权限管理决断器 判断用户拥有的权限或角色是否有资源访问权限 ~~~ @Component public class MyAccessDecisionManager implements AccessDecisionManager { @Override public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(configAttributes==null){ return; } Iterator<ConfigAttribute> iterator = configAttributes.iterator(); while (iterator.hasNext()){ ConfigAttribute c = iterator.next(); String needPerm = c.getAttribute(); for(GrantedAuthority ga : authentication.getAuthorities()) { // 匹配用户拥有的ga 和 系统中的needPerm if(needPerm.trim().equals(ga.getAuthority())) { return; } } } throw new AccessDeniedException("抱歉,您没有访问权限"); } @Override public boolean supports(ConfigAttribute configAttribute) { return true; } @Override public boolean supports(Class<?> aClass) { return true; } } ~~~ * 权限资源管理器 为权限决断器提供支持 ~~~ @Component public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource { @Autowired private PermissionService permissionService; private Map<String, Collection<ConfigAttribute>> map = null; /** * 加载权限表中所有操作请求权限 */ public void loadResourceDefine(){ map = new HashMap<>(16); Collection<ConfigAttribute> configAttributes; ConfigAttribute cfg; // 获取启用的权限操作请求 List<Permission> permissions = permissionService.findByTypeAndStatusOrderBySortOrder(CommonConstant.PERMISSION_OPERATION, CommonConstant.STATUS_NORMAL); for(Permission permission : permissions) { if(StrUtil.isNotBlank(permission.getTitle())&&StrUtil.isNotBlank(permission.getPath())){ configAttributes = new ArrayList<>(); cfg = new SecurityConfig(permission.getTitle()); //作为MyAccessDecisionManager类的decide的第三个参数 configAttributes.add(cfg); //用权限的path作为map的key,用ConfigAttribute的集合作为value map.put(permission.getPath(), configAttributes); } } } /** * 判定用户请求的url是否在权限表中 * 如果在权限表中,则返回给decide方法,用来判定用户是否有此权限 * 如果不在权限表中则放行 * @param o * @return * @throws IllegalArgumentException */ @Override public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException { if(map == null){ loadResourceDefine(); } //Object中包含用户请求request String url = ((FilterInvocation) o).getRequestUrl(); PathMatcher pathMatcher = new AntPathMatcher(); Iterator<String> iterator = map.keySet().iterator(); while (iterator.hasNext()) { String resURL = iterator.next(); if (StrUtil.isNotBlank(resURL)&&pathMatcher.match(resURL,url)) { return map.get(resURL); } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> aClass) { return true; } } ~~~ 复制 * 每次编辑权限信息后刷新内存中的系统权限信息 ~~~ @Autowired private MySecurityMetadataSource mySecurityMetadataSource; //重新加载权限 mySecurityMetadataSource.loadResourceDefine(); ~~~