原创
SpringSecurity自定义权限验证方式以及去除ROLE_前缀
温馨提示:
本文最后更新于 2020年11月14日,已超过 1,469 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
自定义权限验证方式
e.g.以前的方式
@PostMapping("")
@Log(description = "添加菜单")
@PreAuthorize("hasAnyRole('admin','menu:add')")
public Menu create(@RequestBody @Valid Menu model) {
return service.create(model);
}
自定义方式
@PostMapping("")
@Log(description = "添加菜单")
@PreAuthorize("@lzhpo.checkAnyOne('menu:add')")
public Menu create(@RequestBody @Valid Menu model) {
return service.create(model);
}
权限验证配置LzhpoPermissionConfig
:
原理就是:先获取当前用户拥有的权限,再拿注解上的权限去比对用户拥有的权限,是否包含在其中,包含则返回true(有此注解上的权限),否则就返回false(没此注解上的权限)
import com.withive.system.security.AppUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
* 自定义权限认证方式,并且在验证的时候默认给拥有admin权限(ROLE_ADMIN)的用户放行
*
* @author Zhaopo Liu
*/
@Service(value = "lzhpo")
@Slf4j
public class LzhpoPermissionConfig extends AppUser {
/**
* 用户必须包含传入的所有权限
*
* @param permissions
* @return
*/
public Boolean checkAll(String... permissions) {
// 获取当前用户的所有权限
List<String> lzhpoPermissions = getAuthorities();
log.info("当前用户{}拥有的权限{}", getUsername(), lzhpoPermissions);
// 判断当前用户的所有权限是否包含接口上定义的权限
return lzhpoPermissions.contains("ROLE_ADMIN")
|| Arrays.stream(permissions).allMatch(lzhpoPermissions::contains);
}
/**
* 用户只需包含传入的任一权限
*
* @param permissions
* @return
*/
public Boolean checkAnyOne(String... permissions) {
// 获取当前用户的所有权限
List<String> lzhpoPermissions = getAuthorities();
log.info("当前用户{}拥有的权限{}", getUsername(), lzhpoPermissions);
// 判断当前用户的所有权限是否包含接口上定义的权限
return lzhpoPermissions.contains("ROLE_ADMIN")
|| Arrays.stream(permissions).anyMatch(lzhpoPermissions::contains);
}
}
SpringSecurity工具AppUser
:
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
public class AppUser {
public static Optional<SecurityUserDetails> getAppUserPrincipal() {
return Optional.ofNullable(SecurityContextHolder.getContext()).map(SecurityContext::getAuthentication)
.map((x) -> (SecurityUserDetails)x.getPrincipal());
}
public static Optional<SecurityUserDetails> getAppUserPrincipal(Authentication authentication) {
return Optional.of(authentication).map((x) -> (SecurityUserDetails)x.getPrincipal());
}
protected String getUsername() {
return getAppUserPrincipal().orElseThrow().getUsername();
}
protected String getName() {
return getAppUserPrincipal().orElseThrow().getUsername();
}
protected String getUserId() {
return getAppUserPrincipal().orElseThrow().getUserId();
}
protected List<String> getAuthorities() {
return getAppUserPrincipal().stream()
.flatMap(
(Function<SecurityUserDetails, Stream<? extends GrantedAuthority>>)x -> x.getAuthorities().stream())
.map(GrantedAuthority::getAuthority).collect(Collectors.toList());
}
}
去除ROLE_前缀
在继承WebSecurityConfigurerAdapter
的SpringSecurity配置类:
@Override
public void configure(WebSecurity webSecurity) {
// ...
/** 去除SpringSecurity中默认的权限ROLE_前缀 */
webSecurity.expressionHandler(new DefaultWebSecurityExpressionHandler() {
@Override
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
// 去除默认的ROLE_前缀
root.setDefaultRolePrefix("");
return root;
}
});
}
// /**
// * 去除SpringSecurity中默认的权限ROLE_前缀,{@link MyUserDetails#getAuthorities()}
// *
// * @author Zhaopo Liu
// * @return
// */
// @Bean
// GrantedAuthorityDefaults grantedAuthorityDefaults() {
// return new GrantedAuthorityDefaults("");
// }
在实现UserDetails
的类就可以不用加上ROLE_
前缀了。
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new LinkedList<>();
// 添加角色权限
for (Role role : user.getRoles()) {
// authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getCode()));
authorities.add(new SimpleGrantedAuthority(role.getCode()));
// 添加菜单权限
for (Menu menu : role.getMenus()) {
if (menu.getIsEnable() && !menu.getIsDelete()) {
// authorities.add(new SimpleGrantedAuthority("ROLE_" + menu.getCode()));
authorities.add(new SimpleGrantedAuthority(menu.getCode()));
}
}
}
return authorities;
}
- 本文标签: Java SpringSecurity
- 本文链接: http://www.lzhpo.com/article/160
- 版权声明: 本文由lzhpo原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权