博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring security动态配置url权限
阅读量:5740 次
发布时间:2019-06-18

本文共 5644 字,大约阅读时间需要 18 分钟。

  hot3.png

对于使用spring security来说,存在一种需求,就是动态去配置url的权限,即在运行时去配置url对应的访问角色。这里简单介绍一下。

Standard Filter Aliases and Ordering

首先需要了解spring security内置的各种filter:

Alias Filter Class Namespace Element or Attribute
CHANNEL_FILTER ChannelProcessingFilter http/intercept-url@requires-channel
SECURITY_CONTEXT_FILTER SecurityContextPersistenceFilter http
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter session-management/concurrency-control
HEADERS_FILTER HeaderWriterFilter http/headers
CSRF_FILTER CsrfFilter http/csrf
LOGOUT_FILTER LogoutFilter http/logout
X509_FILTER X509AuthenticationFilter http/x509
PRE_AUTH_FILTER AbstractPreAuthenticatedProcessingFilter Subclasses N/A
CAS_FILTER CasAuthenticationFilter N/A
FORM_LOGIN_FILTER UsernamePasswordAuthenticationFilter http/form-login
BASIC_AUTH_FILTER BasicAuthenticationFilter http/http-basic
SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareRequestFilter http/@servlet-api-provision
JAAS_API_SUPPORT_FILTER JaasApiIntegrationFilter http/@jaas-api-provision
REMEMBER_ME_FILTER RememberMeAuthenticationFilter http/remember-me
ANONYMOUS_FILTER AnonymousAuthenticationFilter http/anonymous
SESSION_MANAGEMENT_FILTER SessionManagementFilter session-management
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter http
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor http
SWITCH_USER_FILTER SwitchUserFilter N/A

这里我们要操作的是FilterSecurityInterceptor这个interceptor,使用withObjectPostProcessor来设置

FilterSecurityInterceptor

这个filter有几个要素,如下:

  • SecurityMetadataSource
  • AccessDecisionManager
  • AuthenticationManager

可以根据情况自己去重新设置,这里我们重写一下SecurityMetadataSource用来动态获取url权限配置,还有AccessDecisionManager来进行权限判断。

MyAccessDecisionManager

public class MyAccessDecisionManager implements org.springframework.security.access.AccessDecisionManager {    @Override    public void decide(Authentication authentication, Object object,                       Collection
configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { //这段代码其实不需要,因为spring-security-core-4.1.4.RELEASE-sources.jar!/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java第215行判断提前返回了,不会进入decide方法 if (CollectionUtils.isEmpty(configAttributes)) { throw new AccessDeniedException("not allow"); } Iterator
ite = configAttributes.iterator(); while (ite.hasNext()) { ConfigAttribute ca = ite.next(); String needRole = ((org.springframework.security.access.SecurityConfig) ca).getAttribute(); for (GrantedAuthority ga : authentication.getAuthorities()) { if(ga.getAuthority().equals(needRole)){ //匹配到有对应角色,则允许通过 return; } } } //该url有配置权限,但是当然登录用户没有匹配到对应权限,则禁止访问 throw new AccessDeniedException("not allow"); } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class
clazz) { return true; }}

这里遍历判断该url所需的角色看用户是否具备,有具备则返回,都不具备则抛出AccessDeniedException异常

MyFilterInvocationSecurityMetadataSource

public class MyFilterInvocationSecurityMetadataSource implements org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource {    private final AntPathMatcher antPathMatcher = new AntPathMatcher();    private final Map
urlRoleMap = new HashMap
(){
{ put("/open/**","ROLE_ANONYMOUS"); put("/health","ROLE_ANONYMOUS"); put("/restart","ROLE_ADMIN"); put("/demo","ROLE_USER"); }}; @Override public Collection
getAttributes(Object object) throws IllegalArgumentException { FilterInvocation fi = (FilterInvocation) object; String url = fi.getRequestUrl();// String httpMethod = fi.getRequest().getMethod(); for(Map.Entry
entry:urlRoleMap.entrySet()){ if(antPathMatcher.match(entry.getKey(),url)){ return SecurityConfig.createList(entry.getValue()); } } //没有匹配到,默认是要登录才能访问 return SecurityConfig.createList("ROLE_USER");// return null; } @Override public Collection
getAllConfigAttributes() { return null; } @Override public boolean supports(Class
clazz) { return FilterInvocation.class.isAssignableFrom(clazz); }}

这里以内存的map来展示一下,实际应用可以从分布式配置中心或者数据库中读取,另外循环遍历这个可能消耗性能,必要时得优化一下。

SecurityConfig

最后需要综合配置一下,如下

@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {    @Override    public void configure(HttpSecurity http) throws Exception {        http                .authorizeRequests()                .anyRequest().authenticated()                .withObjectPostProcessor(new ObjectPostProcessor
() { public
O postProcess( O fsi) { fsi.setSecurityMetadataSource(mySecurityMetadataSource()); fsi.setAccessDecisionManager(myAccessDecisionManager()); return fsi; } }); } @Bean public FilterInvocationSecurityMetadataSource mySecurityMetadataSource() { MyFilterInvocationSecurityMetadataSource securityMetadataSource = new MyFilterInvocationSecurityMetadataSource(); return securityMetadataSource; } @Bean public AccessDecisionManager myAccessDecisionManager() { return new MyAccessDecisionManager(); }}

doc

转载于:https://my.oschina.net/go4it/blog/1510448

你可能感兴趣的文章
Linux内存初始化(二)identity mapping和kernel image mapping
查看>>
chmod -x chmod的N种解法
查看>>
41、生鲜电商平台-物流动态费率、免运费和固定运费设计与架构
查看>>
autoit获取ie浏览器简单操作网页(GUI小工具)
查看>>
for...in 和 for each...in的一些区分和用法
查看>>
多项式输出
查看>>
转载:性能优化——统计信息——SQLServer自动更新和自动创建统计信息选项
查看>>
Windows下PHP安全环境的搭建
查看>>
pyqt5和qtdesign的使用
查看>>
MVC-Razor引擎布局
查看>>
C/C++ 段错误--关于指针内存泄露
查看>>
BASH 编程之变量高级篇
查看>>
java中的位运算符
查看>>
今夕七夕
查看>>
EF升级 反射重载方法ApplyConfiguration
查看>>
【HDOJ】1241 Oil Deposits
查看>>
个人作业1——四则运算题目生成程序(基于控制台)
查看>>
Java注解开发与应用案例
查看>>
PS 切HTML (ps+div+css)
查看>>
iftop命令命令详解
查看>>