【SpringSecurity-09】动态加载用户角色权限数据

SpringSecurity 动态加载用户角色权限数据

在这里插入图片描述

  • UserDetails接口表达你是谁?你有什么角色权限?
  • UserDeatilsService接口表达式时如何动态加载UserDetails数据
  • 集成持久层框架(MyBatis Plus)
  • 如何加载用户角色权限数据?结合RBAC权限管理模型理解SQL
  • SpringSecurity配置动态加载的实现
  • 实现效果测试

一、实现UserDetails接口

public class MyUserDetails implements UserDetails {

    String password; //密码
    String username;    //用户名
    boolean accountNonExpired;  //是否没过期
    boolean accountNonLocked;   //是否没被锁定
    boolean credentialsNonExpired;  //是否没过期
    boolean enabled;    //账号是否可用
    Collection<? extends GrantedAuthority> authorities; //用户得权限集合

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setAccountNonExpired(boolean accountNonExpired) {
        this.accountNonExpired = accountNonExpired;
    }

    public void setAccountNonLocked(boolean accountNonLocked) {
        this.accountNonLocked = accountNonLocked;
    }

    public void setCredentialsNonExpired(boolean credentialsNonExpired) {
        this.credentialsNonExpired = credentialsNonExpired;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }
} 

二、UserDetailsService接口

@Component
public class MyUserDetailsService implements UserDetailsService {

    @Resource
    MyUserDetailsServiceMapper myUserDetailsServiceMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //用户基础数据加载
        MyUserDetails myUserDetails = myUserDetailsServiceMapper.findByUserName(username);
        if (myUserDetails == null){
            throw new UsernameNotFoundException("用户名不存在");
        }

        //用户的角色列表
        List<String> roleCodes = myUserDetailsServiceMapper.findRoleByUserName(username);

        //根据角色列表加载当前角色
        List<String> authorities = myUserDetailsServiceMapper.findAuthorityByRoleCodes(roleCodes);

        roleCodes = roleCodes.stream()
                .map(rc -> "ROLE_" + rc)
                .collect(Collectors.toList());

        authorities.addAll(roleCodes);

        myUserDetails.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(
                String.join(",", authorities)
        ));

        return myUserDetails;
    }
}

三、集成持久层框架(MyBatis Plus)

public interface MyUserDetailsServiceMapper {

    //根据userID查询用户信息
    @Select("SELECT username, password, enabled " +
            "FROM sys_user u " +
            "WHERE u.username = #{username}")
    MyUserDetails findByUserName(@Param("username") String username);

    //根据userID查询用户角色
    @Select("SELECT role_code " +
            "FROM sys_role r " +
            "LEFT JOIN sys_user_role ur ON r.id = ur.role_id " +
            "LEFT JOIN sys_user u ON  u.id = ur.user_id " +
            "WHERE u.username = #{userId}")
    List<String> findRoleByUserName(@Param("userId") String userId);

    //根据用户角色查询用户权限
    @Select({
            "<script>",
                "SELECT url ",
                "FROM sys_menu m ",
                "LEFT JOIN sys_role_menu rm ON m.id = rm.menu_id ",
                "LEFT JOIN sys_role r ON r.id = rm.role_id ",
                "WHERE r.role_code IN ",
                "<foreach collection='roleCodes' item='roleCode' open='(' separator=',' close=')'>",
                    "#{roleCode}",
                "</foreach>",
            "</script>"
    })
    List<String> findAuthorityByRoleCodes(@Param("roleCodes") List<String> roleCodes);
}

四、数据库表

sys_user

在这里插入图片描述

sys_role

在这里插入图片描述

sys_menu

在这里插入图片描述

sys_user_role

在这里插入图片描述

sys_role_menu

在这里插入图片描述

五、测试

admin用户可以访问所有路径

user用户只能访问业务一和业务二

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值