【SpringSecurity】SpringSecurity安全框架授权

授权

权限系统要实现的效果:不同的用户可以使用不同的功能

在后台进行用户权限的判断,判断当前用户是否有相应的权限,必须具有所需权限才能进行相应的操作。

在 SpringSecurity 中,默认使用 FilterSecurityInterceptor 进行权限校验。在 FilterSecurityInterceptor 中会从SecurityContextHolder 获取其中的 Authentication,然后获取其中的权限信息。当前用户是否拥有访问当前资源所需的权限。所以我们在项目中只需要把当前登录用户的权限信息也存入 Authentication,然后设置我们的资源所需要的权限即可。

首先开启相关配置。

java 复制代码
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // ......
}

使用对应的注解。@PreAuthorize

java 复制代码
@RestController
@RequestMapping("/user")
public class SysUserController {
    @Resource
    private SysUserService sysUserService;
    // 登录方法......
    // 退出登录......
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('USER1')")
    public ResultJSON list() {
        return ResultJSON.success();
    }
}

封装权限信息

写 UserDetailsServiceImzho 中,在查询出用户后还要获取对应的权限信息,封装到 UserDetails 中返回。

把权限信息写死封装到 UserDetails 中进行测试。

修改 UserDetails 的实现类 LoginUser,让其能封装权限信息。

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginUser implements UserDetails {
    private SysUser sysUser;
    private List<String> permissions;

    public LoginUser(SysUser sysUser, List<String> permissions) {
        this.sysUser = sysUser;
        this.permissions = permissions;
    }
    //存储SpringSecurity所需要的权限信息的集合
    @JSONField(serialize = false)
    private List<GrantedAuthority> authorities;
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if (authorities != null) {
            return authorities;
        }
        authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",",permissions));
        return authorities;
    }
    // 其他方法......
}
java 复制代码
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private SysUserDao sysUserDao;
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        // 根据用户名查询用户信息
        SysUser sysUser = sysUserDao.selectOne(new QueryWrapper<SysUser>()
                .eq("user_name", username));
        if (Objects.isNull(sysUser)) {
            throw new RuntimeException("用户名或密码错误");
        }
        // 从数据库中获取权限列表
        List<String> list = new ArrayList<>;
        list.add("USER1");
        // list.add("USER2");
        // 返回用户信息 和 权限集合
        return new LoginUser(sysUser, list);
    }
}

在 JwtAuthenticationTokenFilter 中修改如下代码

UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());

java 复制代码
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Resource
    private RedisCache redisCache;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //......
        //存入SecurityContextHolder
        //TODO 获取权限信息封装到Authentication中
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(request, response);
    }
}

分别调用接口运行测试

java 复制代码
@RestController
@RequestMapping("/user")
public class SysUserController {
    @Resource
    private SysUserService sysUserService;
    // 登录方法......
    // 退出登录......
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('USER1')")
    public ResultJSON list() {
        return ResultJSON.success();
    }
}
java 复制代码
@RestController
@RequestMapping("/order")
public class SysOrderController {
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('USER2')")
    public ResultJSON list() {
        return ResultJSON.success();
    }
}

从数据库查询权限信息

RBAC 权限模型(Role-Based Access Control)

基于角色的权限控制。这是目前最常被开发者使用也是相对易用、通用权限模型。

相关推荐
·薯条大王8 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
ZJH__GO11 小时前
网络编程v4pro--实现聊天室文件传输功能
java·服务器·网络·计算机网络
程序员黑豆12 小时前
Windows 系统 Java 环境变量配置全攻略:解决“不是内部或外部命令”
java·前端·ai编程
命运之光12 小时前
【C语言完整代码】就诊信息管理系统
java·c语言·开发语言
凤山老林12 小时前
Spring Boot @Async 线上实战:从默认配置到生产级线程池治理
java·spring boot·后端
marvelyu13 小时前
每天10分钟学会OceanBase系列(Day 20):跨机房容灾实战——构建多数据中心高可用架构
java·大数据·数据库
AI人工智能+电脑小能手14 小时前
大白话说Java设计模式-04-工厂方法模式(业务实战篇)
java·设计模式·工厂方法模式·架构设计·代码解耦
BUG指挥官14 小时前
Sa-Token和Spring Security对比
java·后端·spring
小当家.10514 小时前
深入理解 ReAct Agent:从原理到 Java 实战
java·react.js·agent·react·架构设计·agent设计
geminigoth14 小时前
Spring AI Alibaba 入门开发一(备份)
java·人工智能·spring