springboot security 动态权限
时间: 2023-11-20 15:46:38 浏览: 237
springboot springsecurity动态权限控制
5星 · 资源好评率100%
Spring Boot Security 提供了动态权限的支持。动态权限是指在运行时根据特定条件动态地决定用户是否有权限访问某个资源。具体来说,Spring Boot Security 动态权限的实现需要以下步骤:
1. 实现 AccessDecisionVoter 接口来定义投票策略。AccessDecisionVoter 接口有一个 vote 方法,该方法根据特定条件返回投票结果(同意、反对、弃权)。
2. 实现 AccessDecisionManager 接口来定义投票决策。AccessDecisionManager 接口有一个 decide 方法,该方法根据所有投票结果决定用户是否有权限访问某个资源。
3. 在 Spring Security 配置中配置 AccessDecisionManager,以便在运行时进行动态权限判断。
4. 在需要进行动态权限判断的地方使用 @PreAuthorize 或者 @PostAuthorize 注解指定要进行的权限判断。在这些注解中,可以使用 SpEL 表达式指定需要的条件。
5. 在 SpEL 表达式中使用 SecurityContextHolder.getContext().getAuthentication() 方法获取当前用户信息,根据用户信息判断是否有权限访问。
下面是一个简单的动态权限实现示例:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
.accessDecisionManager(accessDecisionManager())
.and().formLogin().loginPage("/login").permitAll()
.and().logout().permitAll();
}
@Bean
public AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<?>> decisionVoters = Arrays.asList(
new RoleVoter(),
new AuthenticatedVoter(),
new CustomVoter(userService)
);
return new AffirmativeBased(decisionVoters);
}
}
public class CustomVoter implements AccessDecisionVoter<Object> {
private UserService userService;
public CustomVoter(UserService userService) {
this.userService = userService;
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
if (authentication == null || !authentication.isAuthenticated()) {
return ACCESS_DENIED;
}
User currentUser = userService.findByUsername(authentication.getName());
if (currentUser == null) {
return ACCESS_DENIED;
}
for (ConfigAttribute attribute : attributes) {
if (attribute.getAttribute().equals(currentUser.getRole())) {
return ACCESS_GRANTED;
}
}
return ACCESS_DENIED;
}
}
@Controller
public class UserController {
@GetMapping("/user/list")
@PreAuthorize("hasRole('USER')")
public String userList(Model model) {
List<User> userList = userService.findAll();
model.addAttribute("userList", userList);
return "user/list";
}
}
```
在上面的示例中,我们首先在 SecurityConfig 中配置了两个角色 ADMIN 和 USER,并在其中使用 accessDecisionManager() 方法配置动态权限判断。这里我们使用了一个自定义的 CustomVoter,该投票器会根据当前用户的角色和资源需要的角色进行匹配,如果匹配成功则返回 ACCESS_GRANTED,否则返回 ACCESS_DENIED。
在 UserController 中,我们使用了 @PreAuthorize 注解指定只有拥有 USER 角色的用户才能访问 /user/list 接口。在 SpEL 表达式中我们使用了 SecurityContextHolder.getContext().getAuthentication() 方法获取当前用户信息,并根据用户信息进行动态权限判断。
阅读全文