【Spring Security】分布式鉴权的使用

这篇具有很好参考价值的文章主要介绍了【Spring Security】分布式鉴权的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

🎉🎉欢迎来到我的CSDN主页!🎉🎉

🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚

🌟推荐给大家我的专栏《Spring Security》。🎯🎯

👉点击这里,就可以查看我的主页啦!👇👇

Java方文山的个人主页

🎁如果感觉还不错的话请给我点赞吧!🎁🎁

💖期待你的加入,一起学习,一起进步!💖💖

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

前言

我们都知道Spring Security是做认证鉴权的框架,为了一些不必要的麻烦,登录功能都是他们自己做的,那我们就需要将登录的功能交给Spring Security管理,但是他们做的东西肯定也是不满足于我们的需求,所以我们要在根据他们提供的代码上自定义,可以将自定义的用户信息获取逻辑集成到Spring Security中,从而实现基于数据库的用户身份认证。

再上一篇中我是通过实现UserDetailsService接口并重写loadUserByUsername方法完成的,但是后面我想了想不应该把代码放在UserServiceImpl层,所以我们需要创建一个类来继承UserServiceImpl将自定义用户身份认证的代码写入。

MyUserDetailsService 

package com.csdn.security.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.csdn.security.pojo.User;
import com.csdn.security.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @author Java方文山
 * @compay csdn_Java方文山
 * @create 2023-12-22-12:10
 */
@Component
public class MyUserDetailsService implements UserDetailsService {
    
    @Autowired
    private UserServiceImpl userService;

    /**
     * 实现Spring Security内置的UserDetailService接口,重写loadUserByUsername方法实现数据库的身份校验
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名查询数据库中用户信息
        User user = userService.getOne(new QueryWrapper<User>().eq("username", username));
        //判断用户是否存在
        if(Objects.isNull(user))
            throw new UsernameNotFoundException("用户不存在");
        //权限校验TODO,后续讲解
        return user;
    }
}

记得我们也要把我们做身份验证这里也改掉,替换成MyUserDetailsService 

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

 一、前期准备

我们将数据相应到前端,肯定需要特定的格式,方便我们前端做数据显示,这里会用到两个类

JsonResponseStatus 

package com.csdn.security.resp;

import lombok.Getter;

@Getter
public enum JsonResponseStatus {

    OK(200, "OK"),
    UN_KNOWN(500, "未知错误"),
    RESULT_EMPTY(1000, "查询结果为空!"),
    ;

    private final Integer code;
    private final String msg;

    JsonResponseStatus(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

}

这个类是一个枚举类,用于定义接口返回的 JSON 响应状态。它包含了一些常见的响应状态,如 OK(200, "OK") 表示请求成功,UN_KNOWN(500, "未知错误") 表示未知错误,RESULT_EMPTY(1000, "查询结果为空!") 表示查询结果为空。每个响应状态都有一个对应的状态码和消息。在接口的返回值中,可以使用这个枚举类来表示具体的响应状态。 

JsonResponseBody

package com.csdn.security.resp;

import lombok.Data;

@Data
public class JsonResponseBody<T> {

    private Integer code;
    private String msg;
    private T data;
    private Long total;

    private JsonResponseBody(JsonResponseStatus jsonResponseStatus, T data) {
        this.code = jsonResponseStatus.getCode();
        this.msg = jsonResponseStatus.getMsg();
        this.data = data;
    }

    private JsonResponseBody(JsonResponseStatus jsonResponseStatus, T data, Long total) {
        this.code = jsonResponseStatus.getCode();
        this.msg = jsonResponseStatus.getMsg();
        this.data = data;
        this.total = total;
    }

    public static <T> JsonResponseBody<T> success() {
        return new JsonResponseBody<T>(JsonResponseStatus.OK, null);
    }

    public static <T> JsonResponseBody<T> success(T data) {
        return new JsonResponseBody<T>(JsonResponseStatus.OK, data);
    }

    public static <T> JsonResponseBody<T> success(T data, Long total) {
        return new JsonResponseBody<T>(JsonResponseStatus.OK, data, total);
    }

    public static <T> JsonResponseBody<T> unknown() {
        return new JsonResponseBody<T>(JsonResponseStatus.UN_KNOWN, null);
    }

    public static <T> JsonResponseBody<T> other(JsonResponseStatus jsonResponseStatus) {
        return new JsonResponseBody<T>(jsonResponseStatus, null);
    }

}

 这个类是一个通用的 JSON 响应体类

  • code:表示响应状态码。
  • msg:表示响应消息。
  • data:表示响应数据的泛型对象。
  • total:表示响应数据的总数。

修改我们登陆成功后的操作,加入一个JSON字符串转换类并将获取到的对象输出到前端。

    //JSON格式转换
    @Autowired
    private ObjectMapper objectMapper;
 //设置登录成功后重定向到那个页面
  .successHandler((req, resp, auth) -> {
    objectMapper.writeValue(resp.getOutputStream(),auth.getPrincipal());
 })

 重启服务器登录进行测试

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

 可以看到我们的数据都响应到前端了,前端人员就可以拿着数据进行操作了

二、分布式鉴权

1.授权介绍

Spring Security 中的授权分为两种类型:

  • 基于角色的授权:以用户所属角色为基础进行授权,如管理员、普通用户等,通过为用户分配角色来控制其对资源的访问权限。

  • 基于资源的授权:以资源为基础进行授权,如 URL、方法等,通过定义资源所需的权限,来控制对该资源的访问权限。

Spring Security 提供了多种实现授权的机制,最常用的是使用基于注解的方式,建立起访问资源和权限之间的映射关系。

其中最常用的两个注解是 @Secured@PreAuthorize@Secured 注解是更早的注解,基于角色的授权比较适用,@PreAuthorize 基于 SpEL 表达式的方式,可灵活定义所需的权限,通常用于基于资源的授权。

2.表设计

我们会用到以下五张表sys_user、sys_user_role、sys_role、sys_role_module、sys_module

sys_user(用户表)

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

sys_user_role(用户角色表)

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

sys_role(角色表)

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java sys_role_module(角色权限表)

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

 sys_module(模块表)

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

3.获取用户权限

我们在数据表都在一个服务器的情况下,可以直接进行联表查询

select * from sys_user a,
              sys_user_role b,
              sys_role_module c,
              sys_module d
where a.id=b.user_id and
      b.role_id=c.role_id and
      c.module_id=d.id

如果我们不是源于一个数据库或者一个服务器,那么就要将数据在后端做处理,先在我们自定义身份验证类也就是MyUserDetailsService类,随后将五个表的service实现类引入

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

 认证身份的同时把权限查询出来。

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名查询数据库中用户信息
        User user = userService.getOne(new QueryWrapper<User>().eq("username", username));
        //判断用户是否存在
        if(Objects.isNull(user))
            throw new UsernameNotFoundException("用户不存在");
        //权限校验TODO
        //.stream().map()遍历所有对象将新的数据放入流中
        // .collect将流中的数据变成一个集合

        //1.先查询出用户拥有的角色
        List<Integer> userId = userRoleService.
                list(new QueryWrapper<UserRole>()
                        .eq("user_id", user.getId()))
                .stream().map(UserRole::getRoleId)
                .collect(Collectors.toList());
        //2.根据角色查询角色名称
        List<String> roleId = roleService
                .list(new QueryWrapper<Role>().in("role_id", userId))
                .stream().map(Role::getRoleName)
                .collect(Collectors.toList());
        //3.根据角色查询角色所拥有模块ID
        List<Integer> ModuleId = roleModuleService
                .list(new QueryWrapper<RoleModule>().in("role_id", userId))
                .stream().map(RoleModule::getModuleId)
                .collect(Collectors.toList());
        //4.根据模块ID查询模块URL
        List<String> urls = moduleService
                .list(new QueryWrapper<Module>().in("id", ModuleId))
                .stream().map(Module::getUrl)
                .collect(Collectors.toList());
        //将用户角色名称与模块url放入一个集合
        roleId.addAll(urls);
        //认证集合对象
        List<SimpleGrantedAuthority> collect = roleId.stream().map(e -> {
            return new SimpleGrantedAuthority(e);
        }).collect(Collectors.toList());
        //将认证集合对象赋值给用户实体
        user.setAuthorities(collect);

        return user;
    }

 这里还有一个问题需要我们解决,我们写完以上代码进行测试后发现有错误

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

该错误很简单出现在对模块URL遍历这里,因为我们的数据库表中有两个值是空的

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

第一个方法是加上url的值

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

第二个方法就是过滤

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

4.修改SpringSecurity配置类

当我们想要开启spring方法级安全时,只需要在任何 @Configuration实例上使用@EnableGlobalMethodSecurity 注解就能达到此目的。同时这个注解为我们提供了prePostEnabled securedEnabled jsr250Enabled 三种不同的机制来实现同一种功能。

修改WebSecurityConfig配置类,开启基于方法的安全认证机制,也就是说在web层的controller启用注解机制的安全确认。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
    ...
}

@EnableGlobalMethodSecurity是Spring Security提供的一个注解,用于启用方法级别的安全性。它可以在任何@Configuration类上使用,以启用Spring Security的方法级别的安全性功能。它接受一个或多个参数,用于指定要使用的安全注解类型和其他选项。以下是一些常用的参数:

  • prePostEnabled:如果设置为true,则启用@PreAuthorize@PostAuthorize注解。默认值为false

  • securedEnabled:如果设置为true,则启用@Secured注解。默认值为false

  • jsr250Enabled:如果设置为true,则启用@RolesAllowed注解。默认值为false

  • proxyTargetClass:如果设置为true,则使用CGLIB代理而不是标准的JDK动态代理。默认值为false

使用@EnableGlobalMethodSecurity注解后,可以在应用程序中使用Spring Security提供的各种注解来保护方法,例如@Secured@PreAuthorize@PostAuthorize@RolesAllowed。这些注解允许您在方法级别上定义安全规则,以控制哪些用户可以访问哪些方法。

注解介绍:

注解 说明
@PreAuthorize 用于在方法执行之前对访问进行权限验证
@PostAuthorize 用于在方法执行之后对返回结果进行权限验证
@Secured 用于在方法执行之前对访问进行权限验证
@RolesAllowed 是Java标准的注解之一,用于在方法执行之前对访问进行权限验证

5.控制Controller层接口权限


    @PreAuthorize("hasAuthority('order:manager:list')")
    @RequestMapping("/queryRoles")
    public String  queryRoles(){
        return "管理员权限";
    }

    @PreAuthorize("hasAnyAuthority('book:manager:list','order:manager:list')")
    @RequestMapping("/queryModules")
    public String queryModules(){
        return "管理员权限/用户权限";
    }

至此我们的鉴权就全部完成了

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java

到这里我的分享就结束了,欢迎到评论区探讨交流!!

💖如果觉得有用的话还请点个赞吧 💖

【Spring Security】分布式鉴权的使用,# Spring Security,spring,分布式,java文章来源地址https://www.toymoban.com/news/detail-786803.html

到了这里,关于【Spring Security】分布式鉴权的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Spring Cloud实战 |分布式系统的流量控制、熔断降级组件Sentinel如何使用

    Spring Cloud实战 |分布式系统的流量控制、熔断降级组件Sentinel如何使用

    专栏集锦,大佬们可以收藏以备不时之需 Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏:https://blog.csdn.net/superdangbo/category_9271502.html tensorflow专栏:https://blog.csdn.net/superdangbo/category_869

    2024年02月04日
    浏览(20)
  • 新版onenet平台安全鉴权的确定与使用

    新版onenet平台安全鉴权的确定与使用

      根据onenet官方更新的文档:平台提供开放的API接口,用户可以通过HTTP/HTTPS调用,进行设备管理,数据查询,设备命令交互等操作,在API的基础上,根据自己的个性化需求搭建上层应用。    为提高API访问安全性,OneNET API的鉴权参数作为header的authorization参数存在。 安全鉴权

    2024年02月04日
    浏览(7)
  • 【Spring Boot Admin】使用(整合Spring Security服务,添加鉴权)

    【Spring Boot Admin】使用(整合Spring Security服务,添加鉴权)

    Spring Boot Admin 监控平台 背景:Spring Boot Admin 监控平台不添加鉴权就直接访问的话,是非常不安全的。所以在生产环境中使用时,需要添加鉴权,只有通过鉴权后才能监控客户端服务。本文整合Spring Security进行实现。 pom依赖 yml配置 启动类@EnableAdminServer 安全配置类:SecuritySe

    2024年02月16日
    浏览(29)
  • 在Spring中,可以使用不同的方式来实现分布式锁,例如基于数据库、Redis、ZooKeeper等

    在Spring中,可以使用不同的方式来实现分布式锁,例如基于数据库、Redis、ZooKeeper等

    在Spring中,可以使用不同的方式来实现分布式锁,例如基于数据库、Redis、ZooKeeper等。下面是两种常见的实现方式: 使用Redis实现分布式锁: 使用自定义注解实现本地锁: 以上是两种常见的在Spring中实现分布式锁的方式。第一种方式使用Redis作为分布式锁的存储介质,通过

    2024年03月17日
    浏览(15)
  • .NET CORE开源 DDD微服务 支持 多租户 单点登录 多级缓存、自动任务、分布式、日志、授权和鉴权 、网关 、注册与发现 系统架构 docker部署

    .NET CORE开源 DDD微服务 支持 多租户 单点登录 多级缓存、自动任务、分布式、日志、授权和鉴权 、网关 、注册与发现 系统架构 docker部署

    源代码地址https://github.com/junkai-li/NetCoreKevin 基于NET6搭建跨平台DDD思想WebApi架构、IDS4单点登录、多缓存、自动任务、分布式、多租户、日志、授权和鉴权、CAP、SignalR、 docker部署  如需简约项目可直接去除项目引用 解耦设计都可以单独引用 架构默认全部引用并启动 项目启动时

    2023年04月24日
    浏览(9)
  • 分布式链路追踪专栏,Spring Cloud Sleuth:分布式链路追踪之通信模型设计

    分布式链路追踪专栏,Spring Cloud Sleuth:分布式链路追踪之通信模型设计

    Spring Cloud Sleuth  赋予分布式跟踪的  Spring Boot  自动配置的一键解决方案。 Spring Cloud Sleuth  是基于  Brave  的封装,也是很多公司采用开源加自研的最佳解决方案。 那么从作为架构师或者技术专家如何去借鉴优秀框架的设计理念和思想,本次  Chat  将开启作者既分布式链路

    2024年01月19日
    浏览(16)
  • Spring Cloud Alibaba 最新版本(基于Spring Boot 3.1.0)整合完整使用及与各中间件集成
Sleuth+Zipkin集成分布式链路追踪

    Spring Cloud Alibaba 最新版本(基于Spring Boot 3.1.0)整合完整使用及与各中间件集成 Sleuth+Zipkin集成分布式链路追踪

    目录 前言 源码地址 官方中文文档 使用版本 spring Spring Boot 3.1.0 中间件 使用到的组件与功能 环境安装 虚拟机 nexus nacos 集成过程 工程搭建 父工程搭建 子工程 服务集成 nacos集成 配置文件 服务注册与发现-discovery 服务注册 启动 服务发现 测试 配置管理-config 新增配置  测试

    2024年02月12日
    浏览(43)
  • spring boot + minio 分布式文件上传

    spring boot + minio 分布式文件上传

    1、分布式文件系统 简单理解为:一个计算机无法存储海量的文件,通过网络将若干计算机组织起来共同去存储海量的文件,去接收海量用户的请求,这些组织起来的计算机通过网络进行通信。 好处: 一台计算机的文件系统处理能力扩充到多台计算机同时处理。 一台计算机

    2024年02月08日
    浏览(11)
  • Spring Boot 集成 Redisson分布式锁

    Spring Boot 集成 Redisson分布式锁

            Redisson 是一种基于 Redis 的 Java 驻留集群的分布式对象和服务库,可以为我们提供丰富的分布式锁和线程安全集合的实现。在 Spring Boot 应用程序中使用 Redisson 可以方便地实现分布式应用程序的某些方面,例如分布式锁、分布式集合、分布式事件发布和订阅等。本篇

    2024年02月10日
    浏览(19)
  • Spring Boot如何实现分布式消息队列

    Spring Boot如何实现分布式消息队列

    在分布式系统中,消息队列是非常重要的一部分,可以帮助开发人员实现异步处理、解耦系统、提高系统可靠性等。本文将介绍如何使用 Spring Boot 实现分布式消息队列。 消息队列是一种存储消息的容器,可以缓存消息并在需要的时候按照一定的规则将消息发送给消费者。常

    2024年02月14日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包