2

SpringSecurity自定义权限验证方式以及去除ROLE_前缀

 3 years ago
source link: http://www.lzhpo.com/article/160
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SpringSecurity自定义权限验证方式以及去除ROLE_前缀

自定义权限验证方式

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")@Slf4jpublic 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_前缀了。

@Overridepublic 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开发

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK