栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

整合springsecurity实现基于RBAC的用户登录

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

整合springsecurity实现基于RBAC的用户登录

svbadmin学习日志

第一节 spring boot 模块化构建项目
第二节 整合mybatisplus完成用户增删改查
第三节 整合springsecurity实现基于RBAC的用户登录


文章目录
  • svbadmin学习日志
  • 前言
  • 一、基于RBAC的权限控制
  • 二、添加spring security
    • 1.admin-web加入依赖
    • 2.创建实体类
    • 3.创建UserService
    • 3.创建UserMapper
    • 4.创建配置文件
  • 三 使用apifox测试
  • 总结
  • 问题
  • 代码地址


前言

权限认证中还是spring security 用的比较多,不过spring boot 2.7以后有些配置有改动。


一、基于RBAC的权限控制

RBAC就不多介绍了,没听过的同学可以看下底下的参考文档。加上之前建立的user表共五张表,如下(建表sql语句可以到文章最后的代码链接中找到):

二、添加spring security

以下只贴核心代码,完整代码可以到文章最后的代码链接中找到

1.admin-web加入依赖

    org.springframework.boot
    spring-boot-starter-security

2.创建实体类

User 需实现 UserDetails 以及 Role 和 Permission

@TableField(exist = false)
private List roles;
@Override
public Collection getAuthorities() {
    List authorities = new ArrayList<>();
    for (Role role: roles) {
        authorities.add(new SimpleGrantedAuthority(role.getName()));
    }
    return authorities;
}
3.创建UserService

UserServiceImpl 需要实现UserDetailsService

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

    QueryWrapper queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("username",username);
    User user = userMapper.selectOne(queryWrapper);
    System.out.println(user);
    if (user == null){
        throw new UsernameNotFoundException("账户不存在");
    }
    user.setRoles(userMapper.getUserRolesByUid(user.getId()));
    System.out.println(user);
    return user;
}
3.创建UserMapper

UserMapper 要继承 BaseMapper

//根据用户id,获得他所有的角色
List getUserRolesByUid(BigInteger id);
//获取用户列表,及其包含的角色信息
List getUsersWithRoles();

如果要在mapper中自定查询方法,需要在admin-mapper中创建resources文件,然后创建xml

4.创建配置文件

主配置文件 SecurityConfiguration

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .withObjectPostProcessor(new ObjectPostProcessor() {
                @Override
                public  O postProcess(O object) {
                    object.setSecurityMetadataSource(cfisms());
                    object.setAccessDecisionManager(cadm());
                    return object;
                }
            })
            .and()
            .formLogin()
            .loginProcessingUrl("/login").permitAll()
            .and()
            .csrf().disable()
            .userDetailsService(userService);
    return http.build();
}

根据请求路径筛选角色配置

@Override
public Collection getAttributes(Object object) throws IllegalArgumentException {
    FilterInvocation filterInvocation = (FilterInvocation) object;
    String requestUrl =filterInvocation.getRequestUrl(); // 请求url
    String method = filterInvocation.getHttpRequest().getMethod(); // 请求的方法
    List allPermission = permissionMapper.getAllPermissions();
    List roleArr = new ArrayList();
    for (Permission permission : allPermission) {
        if(antPathMatcher.match(permission.getPattern(),requestUrl)){ // 先判断URL路径是否符合
            if ("ANY".equals(permission.getMethod())
                    || method.equals(permission.getMethod())){  // 再判断方法是否符合
                List roles = permission.getRoles();
                for (int i = 0; i < roles.size(); i++) {
                    roleArr.add(roles.get(i).getName());
                }
            }
        }
    }
    if (roleArr.size() > 0){ // 找到匹配的角色
        String[] roleNames = new String[roleArr.size()];
        roleArr.toArray(roleNames);
        return SecurityConfig.createList(roleNames);
    }
    return SecurityConfig.createList("ROLE_LOGIN");
}

匹配登录角色配置

public void decide(Authentication auth, Object object, Collection ca) throws AccessDeniedException, InsufficientAuthenticationException {
    Collection authorities = auth.getAuthorities();// 当前用户拥有的角色
    for (ConfigAttribute configAttribute : ca) { // 当前URL需要的角色
        if ("ROLE_LOGIN".equals(configAttribute.getAttribute()) && auth instanceof UsernamePasswordAuthenticationToken){
            return; // 无需权限的直接访问
        }
        for (GrantedAuthority authority : authorities) {
            if (configAttribute.getAttribute().equals(authority.getAuthority())){ // 找到匹配项
                return;
            }
        }
    }
    throw new AccessDeniedException("权限不足");
}
三 使用apifox测试

这里由于还没有集成jwt,测试的时候还是基于Cookie的。可以先用浏览器访问登陆界面获得到Cookie值,然后放到apifox中测试POST接口。

使用 user/123 登陆,获得Cookie。

由于user这个用户并没有新增用户的权限,所以POST的新增请求返回的是403。

如果使用 admin/123 登陆,则可以顺利新增成功。

如此,基于RBAC的标准restful请求已完成。


总结
  1. spring boot 2.7 以后废弃了WebSecurityConfigurerAdapter ,需要注意
  2. 为了实现标准restful请求的规范,我们在permission这边表加入了method这个字段用来判断

问题
  1. SpringBoot整合SpringSecurity出现Illegal overloaded getter method with ambiguous type for property enable
  2. 进入 SpringBoot2.7,有一个重要的类过期了

代码地址

代码


参考文档:
RBAC简介
如何使用postman测试springsecurity的代码

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021014.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号