SpringSecurity----------基于数据库的授权流程

本文介绍了基于角色的访问控制(RBAC)在SpringSecurity中的应用,重点讲解了如何通过UserDetailsService实现用户身份认证和权限管理,以及如何在自定义的UmsSysUser实体类中存储和获取权限信息。
摘要由CSDN通过智能技术生成

一. RABC介绍

        RBAC【Role-based access control】,增加了角色的概念,即基于角色的访问控制,将权限分配给角 色,再将角色分配给用户。简单来说,就是【用户关联角色,角色关联权限】。

RBAC遵循三条安全原则:

        最小权限原则:给角色配置最小但能满足使用需求的权限。

        责任分离原则:给比较重要或者敏感的事件设置不同的角色,不同的角色间是相互约束的,由其一 同参与完成。

        数据抽象原则:每个角色都只能访问其需要的数据,而不是全部数据,不同的角色能访问到的数据 也不同。

二、SpringSecurity 权限认证

        SpringSecurity要求将身份认证信息存到GrantedAuthority对象列表中。代表了当前用户的权限。 GrantedAuthority对象由AuthenticationManager插入到Authentication对象中,然后在做出授权决策 时由AccessDecisionManager实例读取。

        可以看到UserDetails中有个Collection<? extends GrantedAuthority> 方法,权限列表就是放在这个集合里面的;一个用户的权限是在用户登录的时候,获取用户的所有权限(具体逻辑代码可以通过自定义Service,实现UserDetailsService接口,并且实现loadUserByUsername方法,在这个方法里面通过查询数据库来获取用户的授权信息)。

        自定义的实体类应该是怎样的??

@Data
@TableName("ums_sys_user")
public class UmsSysUser implements Serializable, UserDetails {

    @TableId
    private Long id;
    private String username;
    private String nickname;
    private String email;
    private Integer sex;
    private String avatar;
    private String password;
    private Integer status;
    private Long creator;
    private Long updater;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    @TableLogic
    private Integer deleted;
    private String remark;

    //角色信息
    private Set<UmsRole> roleSet = new HashSet<>();

    //授权信息
    private Set<String> perms = new HashSet<>();

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        //将权限告知给SpringSecurity.通过lambda表达式将String转成set<G>
        if(perms != null && perms.size() > 0){
            //返回权限信息 set类型
            return perms.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet());
        }
        return null;
    }


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

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

    @Override
    public boolean isAccountNonExpired() {
        return status == 0;
    }

    @Override
    public boolean isAccountNonLocked() {
        return status == 0;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return status == 0;
    }

    @Override
    public boolean isEnabled() {
        return status == 0;
    }
}

实现UserDetails 接口,重写getAuthorities方法,可以加上一个属性,作为存放权限的容器,获取的时候直接返回这个集合即可,在loadUserByUsername中就可以这样写:

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

        log.info("loadUserByUsername ==== > {}",username);
        //1.查询角色信息
        UmsSysUser umsSysUser = umsSysUserMapper.selectUserByUsername(username);
        //2.查询权限信息
        if(umsSysUser != null){

            //角色集合
            Set<UmsRole> roleSet = umsSysUser.getRoleSet();

            //角色ID集合
            HashSet<Long> roleIdSet = new HashSet<>(roleSet.size());

            //获取用户的权限列表
            for (UmsRole umsRole : roleSet) {
                roleIdSet.add(umsRole.getRoleId());
            }

            // 用户权限列表
            Set<String> perms = umsSysUser.getPerms();

            //权限查询
            Set<UmsMenu> umsMenus = menuMapper.selectMenuByRoleId(roleIdSet);

            //把权限都放到perms集合中去。
            for (UmsMenu umsMenu : umsMenus) {
                perms.add(umsMenu.getPerms());
            }
            log.info("有权限 ========> {}",umsSysUser);
        }
        //返回一个用户信息,里面包括角色信息和权限信息。
        return umsSysUser;
    }

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值