首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【spring-security基础】基于角色及权限的认证

【spring-security基础】基于角色及权限的认证

作者头像
master336
发布2026-06-15 19:12:35
发布2026-06-15 19:12:35
820
举报
目录

  • 权限结构设计
    • RABC权限模型
    • 权限数据结构设计
    • 数据示例
  • 代码实现
    • UserDetails查询用户所有角色及权限
    • 开启注解
    • 编写测试接口
    • 测试结果
  • 注解说明
  • 实现代码以【spring-security基础】基于数据库的认证方式 为前提

权限结构设计

RABC权限模型

这部分网上资料较多,不再赘述;

在这里插入图片描述
在这里插入图片描述

用户拥有1或多个角色,一个角色拥有多种权限。

权限数据结构设计

在这里插入图片描述
在这里插入图片描述

数据示例

  • user_info
在这里插入图片描述
在这里插入图片描述
  • role_info
在这里插入图片描述
在这里插入图片描述
  • permiss_info
在这里插入图片描述
在这里插入图片描述
  • user_role
在这里插入图片描述
在这里插入图片描述
  • role_permission
在这里插入图片描述
在这里插入图片描述

代码实现

UserDetails查询用户所有角色及权限

查询角色及权限代码示例

代码语言:javascript
复制
public UserDetails loadUserByUsername(String usename) throws UsernameNotFoundException {
        // 查询数据库
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",usename);
        UserInfo userInfo = userInfoDao.selectOne(queryWrapper);
        if (userInfo ==null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        // 获取用户角色
        List<String> roles = rolePermissionDao.getRuleByUserId(userInfo.getId());
        // 获取用户权限(url)
        List<String> per = rolePermissionDao.getPermissByUserId(userInfo.getId());
        for (String role : roles) {
            per.add("ROLE_"+role);
        }
        List<GrantedAuthority> auths = new ArrayList<>();
        for (String s : per) {
            GrantedAuthority e = new SimpleGrantedAuthority(s);
            auths.add(e);
        }
        // 返回认证主体UserDetails
        return new User(userInfo.getUsername(),userInfo.getPassword(),auths);
        //使用非自定义的密码,可能需要进行加密后再放置进认证主体密码属性中去
        // return new User(userInfo.getUsername(),bCryptPasswordEncoder.encode(userInfo.getPassword()),auths);
    }

查询角色及权限相关sql:

代码语言:javascript
复制
import cn.com.demo.entity.RolePermission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface RolePermissionDao extends BaseMapper<RolePermission> {
    /**
     * 获取用户角色
     * @param userId
     * @return
     */
    @Select({"SELECT ri.role_name FROM user_role ur INNER JOIN role_info ri ON ri.id = ur.role_id " +
            " WHERE ur.user_id = #{userId}"})
    List<String> getRuleByUserId(Integer userId);
    /**
     * 获取用户权限
     * @param userId
     * @return
     */
    @Select({"SELECT per.permiss_value FROM user_role ur INNER JOIN role_permission rp ON ur.role_id = rp.role_id" +
            " INNER JOIN permission_info per ON per.id = rp.per_id" +
            " WHERE ur.user_id = #{userId}"})
    List<String> getPermissByUserId(Integer userId);
}

开启注解

代码语言:javascript
复制
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
// 开启鉴权注解
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
// 配置MybatisMapper扫描路径
@MapperScan("cn.com.demo.dao.**")
@SpringBootApplication(scanBasePackages = "cn.com.demo.**")
public class SecurityApplication {
    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class,args);
    }
}

编写测试接口

代码语言:javascript
复制
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/demo")
public class DemoController {
    @GetMapping("/test")
    public String test(){
        return "OK";
    }
    @GetMapping("/info")
    public String info(){
        return SecurityContextHolder.getContext().getAuthentication().getName();
    }
    @GetMapping("/p1")
    @Secured({"ROLE_admin"})
    //@PreAuthorize("hasAnyAuthority('p1')")
    public String p1(){
        return "p1";
    }
    @GetMapping("/p2")
    @Secured({"ROLE_test"})
    //@PreAuthorize("hasAnyAuthority('p2')")
    public String p2(){
        return "p2";
    }
    @GetMapping("/t1")
    @PreAuthorize("hasAnyAuthority('/demo/t1')")
    public String t1(){
        return "t1";
    }
    @GetMapping("/t2")
    @PreAuthorize("hasAnyAuthority('/demo/t2')")
    public String t2(){
        return "t2";
    }
}

测试结果

用户

角色

权限

可访问地址

admin

admin

/demo/t1

/demo/t1,/demo/p1

test

test

/demo/t2

/demo/t2,/demo/p2

注解说明

  • @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) 开启注解及类型
  • @Secured({“ROLE_test”}) 基于角色的注解
  • @PreAuthorize(“hasAnyAuthority(’/demo/t1’)”) 进入方法前验证
  • @PostAuthorize(“hasAnyAuthority(’/demo/t1’)”) 方法执行完毕后验证
  • @PostFilter(“object == admin”) 方法执行之后结果过滤,value使用Spring EL表达式
  • @PreFilter(“object == admin”) 方法执行之前参数过滤, value使用Spring EL表达式
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 权限结构设计
    • RABC权限模型
    • 权限数据结构设计
    • 数据示例
  • 代码实现
    • UserDetails查询用户所有角色及权限
    • 开启注解
    • 编写测试接口
    • 测试结果
  • 注解说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档