springbootsecurity动态权限
时间: 2023-11-16 08:50:31 浏览: 106
springboot springsecurity动态权限控制
5星 · 资源好评率100%
Spring Boot Security 允许你在运行时动态授予或撤销权限。这是通过 `SecurityContextHolder` 管理当前用户的安全上下文实现的。
以下是实现动态权限授权的步骤:
1. 创建一个自定义的实现 `AccessDecisionVoter` 接口的投票器类,用于决定是否授权访问。
```java
@Component
public class CustomAccessDecisionVoter implements AccessDecisionVoter<Object> {
@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) {
// 从上下文中获取当前用户的权限列表
List<String> roles = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
// 判断用户是否有访问权限
for (ConfigAttribute attribute : attributes) {
if (roles.contains(attribute.getAttribute())) {
return ACCESS_GRANTED;
}
}
return ACCESS_DENIED;
}
}
```
2. 在 `WebSecurityConfigurerAdapter` 子类中配置 `AccessDecisionManager`,并将自定义的投票器添加到其中。
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAccessDecisionVoter customAccessDecisionVoter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.accessDecisionManager(accessDecisionManager())
.and()
.formLogin()
.and()
.logout();
}
@Bean
public AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<?>> decisionVoters = Arrays.asList(customAccessDecisionVoter);
return new AffirmativeBased(decisionVoters);
}
}
```
3. 在需要动态授权的地方,将权限信息添加到当前用户的安全上下文中。
```java
@Service
public class UserService {
public void addRoleToUser(String username, String role) {
// 根据用户名获取用户信息
User user = getUserByUsername(username);
// 创建一个新的授权对象
List<GrantedAuthority> authorities = new ArrayList<>(user.getAuthorities());
authorities.add(new SimpleGrantedAuthority(role));
Authentication newAuth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), authorities);
// 将新的授权对象设置到安全上下文中
SecurityContextHolder.getContext().setAuthentication(newAuth);
}
}
```
阅读全文