SpringSecurity自定义权限

SpringSecurity对权限的校验主要有注解路径校验。本文主要解释基于路径校验。

SpringSecurity对权限的校验主要通过FilterSecurityInterceptor这个过滤链实现的。

FilterSecurityInterceptor实现权限校验主要流程

FilterSecurityInterceptor源码

 FilterSecurityInterceptor主要通过doFilter()中的invoke()方法。

 在调用父类的beforeInvocation()方法。

 

Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource().getAttributes(object);

这个过程主要是获取访问当前路径所需要的权限集合attributes ,所以我们可以定义个类,继承FilterInvocationSecurityMetadataSource接口,重写里面的getAttributes()方法,这样就可以实现根据数据库动态获取路径对应的权限信息集合。

 attemptAuthorization(object, attributes, authenticated);

这个方法调用的主要为

 this.accessDecisionManager.decide(authenticated, object, attributes);

这个方法的主要作用是对权限的判断,是否有权限。所有可以实现AccessDecisionManager接口里面的decide()方法,自定义判断该用户是否有权限。

总结:综上所述,我们可以实现FilterInvocationSecurityMetadataSource,AccessDecisionManager这两个接口,在配置到SecurityConfig的配置类型,就可以实现自定义权限。

### 如何在 Spring Security 中实现自定义权限 #### 背景介绍 Spring Security 提供了一种灵活的方式来管理应用程序的安全性,其中包括基于角色的访问控制 (RBAC)[^1]。为了满足更复杂的业务需求,开发者可以通过扩展 `AuthorizationManager` 或者重写默认的行为来实现自定义权限逻辑。 以下是一个完整的解决方案,展示如何通过 Spring Security 的 Bean 配置支持以及延迟认证查找机制[^2] 来实现自定义授权功能。 --- #### 步骤一:创建自定义权限映射 首先,在服务器启动时初始化 URL 到权限的映射关系。这种映射通常存储在一个 Map 结构中,其中 key 是请求路径,value 是所需的权限列表[^3]。 ```java @Configuration public class CustomPermissionConfig { @Bean public Map<String, List<String>> permissionMap() { Map<String, List<String>> map = new HashMap<>(); map.put("/admin/**", Arrays.asList("ROLE_ADMIN")); map.put("/user/**", Arrays.asList("ROLE_USER")); map.put("/finance/**", Arrays.asList("ROLE_FINANCE")); return map; } } ``` 上述代码片段展示了如何将不同的资源路径与其所需的角色关联起来。 --- #### 步骤二:实现自定义 AuthorizationManager 接下来,需要编写一个实现了 `AuthorizationManager<RequestAuthorizationContext>` 接口的类,用于评估用户的权限是否匹配当前请求的需求。 ```java @Component public class CustomAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> { private final Map<String, List<String>> permissionMap; public CustomAuthorizationManager(Map<String, List<String>> permissionMap) { this.permissionMap = permissionMap; } @Override public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, RequestAuthorizationContext context) { String requestedUrl = context.getRequest().getPath().toString(); // 查找对应 URL 所需的权限 List<String> requiredAuthorities = findRequiredAuthorities(requestedUrl); return authentication.map(auth -> { Collection<? extends GrantedAuthority> authorities = auth.getAuthorities(); boolean hasPermission = requiredAuthorities.stream() .anyMatch(authority -> authorities.contains(new SimpleGrantedAuthority(authority))); return new AuthorizationDecision(hasPermission); }).defaultIfEmpty(new AuthorizationDecision(false)); } private List<String> findRequiredAuthorities(String url) { return permissionMap.entrySet().stream() .filter(entry -> Pattern.matches(entry.getKey(), url)) .findFirst() .map(Map.Entry::getValue) .orElse(Collections.emptyList()); } } ``` 这段代码的核心在于解析传入的 HTTP 请求并验证其是否有足够的权限执行操作。 --- #### 步骤三:集成到 Spring Security 配置 最后一步是将自定义的 `CustomAuthorizationManager` 整合到全局安全配置中。 ```java @EnableWebFluxSecurity public class SecurityConfiguration { @Autowired private CustomAuthorizationManager customAuthorizationManager; @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { return http.authorizeExchange(exchanges -> exchanges.anyExchange().access(customAuthorizationManager)) .csrf(csrf -> csrf.disable()) .build(); } } ``` 在此处,我们禁用了 CSRF 保护以便简化示例,并为所有的端点指定了我们的自定义授权器。 --- #### 总结 以上过程描述了一个典型的自定义权限控制系统的设计与实现方式。它利用了 Spring Security 提供的强大框架特性,同时保持了高度可维护性和灵活性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

隔山看水

你的鼓励与打赏是我创作的最大动

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值