Springboot +spring security,基于内存模型实现授权

news2024/12/22 13:17:24

一.简介

1.1概念

所谓授权,举个例子:某个用户想要访问某个资源(接口、页面、功能等),我们应该先去检查该用户是否具备对应的权限,如果具备就允许访问,如果不具备,则不允许访问。也就是说,授权是用来判断控制用户是否就有相应权限的问题的!

在我们认证之后,才会考虑授权的问题,也就是你得先登录进来,然后才有资格判断你有没有权限

1.2粒度

在开始授权之前,先讲下什么叫"粒度",授权粒度就是对授权细分的级别、程度的意思。

在Spring Security中,授权粒度有如下几种:

  1. 支持基于 URL 的请求授权
  2. 基于方法访问的授权
  3. 基于对象访问的授权

一共3种授权粒度,但是对于开发来说,常用的是基于URL和方法两种粒度进行授权。

1.3授权实现方式

想实现授权,可以采用如下方式:

  1. 基于内存模型实现授权
  2. 基于默认数据库模型实现授权
  3. 基于自定义数据库模型实现授权

这篇文章中先学习基于内存模型来实现授权的方法,但是对于该实现方案,在真正开发时几乎不用。只做学习使用。

二. 创建SpringSecurity项目

参考之前的文章,这边不做叙述。

三. 基于内存模型实现授权

3.1创建测试接口

在开始授权代码之前,先创建3个用于测试的Web接口,分别供3个不同的用户角色来进行操作。

3.1.1创建/admin/hello接口:

AdminController 类代码如下:

@RestController
@RequestMapping("/admin")
public class AdminController {
 
    @GetMapping("/hello")
    public String hello() {
        return "hello, admin";
    }
}

3.1.2创建/user/hello接口:

UserController 类代码如下:

@RestController
@RequestMapping("/user")
public class UserController {
 
    @GetMapping("hello")
    public String hello() {
        return "hello, user";
    }
}

3.1.3创建/visitor/hello接口:

VisitorController 类代码如下:

@RestController
@RequestMapping("/visitor")
public class VisitorController {
 
    @GetMapping("/hello")
    public String hello() {
        return "hello, visitor";
    }
}

对于以上三个接口,做如下解释:

  1. /visitor/hello 任何人都可以访问;
  2. /admin/hello 具有 admin 角色的人才能访问;
  3. /user/hello 具有 user 角色的人才能访问;
  4. 所有 user 角色能够访问的接口资源,admin 角色也都能够访问。

4.2配置资源访问权限

先定义一个SecurityConfig配置类,在该类中对各接口进行授权配置,代码如下:

@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasRole("ADMIN")
                .antMatchers("/user/**")
                .hasAnyRole("USER","ADMIN")
                .antMatchers("/visitor/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .permitAll();
    }
}

上面代码含义如下:

  1. 如果请求的路径是 “/admin/**” 开头的接口,用户需要具有 admin 角色;
  2. 如果请求的路径是 “/user/**” 开头的接口,用户需要具有 user 或 admin 角色;
  3. 如果请求的路径是 “/visitor/**” 开头的接口,哪个用户都可以随便访问;
  4. 剩余的其他格式的请求路径,必须认证(登录)后才可以访问。

注意:

代码中配置规则的顺序非常重要!和 Shiro 类似,Spring Security 在匹配的时候也是按照从上往下的顺序来进行匹配,一旦匹配到了就不再继续匹配了。

利用上面的配置规则,我们就可以对相应的接口进行限制了,这时候这些接口,就不是你想访问就能访问的了,你必须拥有对应的角色或者权限才行。

4.3Ant匹配符

采用了 Ant 风格的路径匹配符,它的匹配规则如下:
代码如下:

4.4基于内存模型创建用户角色

对各种接口进行限制后,接下来我们要给用户分配角色权限才行,否则用户是没办法访问有些接口的。那么怎么给用户分配角色呢?

在Spring Security4.x版本中,我们登陆的用户有一个默认的ROLE_USER角色,但是在Spring Security5.x版本中,把这个默认的角色给去掉了。此时访问我们的接口时,如果用户没有被分配相关的角色权限,即使用户登录成功,也未必可以访问接口。只能自己给用户手动分配角色。

Spring Security中基于内存创建用户角色,有两种方式:

  1. 在configure(AuthenticationManagerBuilder auth)方法中定义;
  2. 创建UserDetailsService对象。

这两种方式其实用哪一种都可以,无所谓优劣,看个人习惯。

4.5创建分配角色的第一种方式configure()

先来看看第一种实现方式,这个实现方式主要是利用AuthenticationManagerBuilder来进行实现

在上面创建的SecurityConfig类中,添加一个新的configure()方法,创建用户,并给该用户分配用户名、密码、角色权限等信息,并对该用户的密码采用不加密。代码如下:

@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    ......
        
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser(User.withUsername("admin").password("123").roles("ADMIN", "USER").build())
            .withUser(User.withUsername("user").password("123").roles("USER").build())
            //设置密码编码器
            .passwordEncoder(NoOpPasswordEncoder.getInstance());
    }       
    
   ......     
}   

通过这几行代码,我们就在内存中创建了2个用户,分别是admin和user用户,密码都是123。

4.6创建分配角色的第二种方式UserDetailsService

第二种创建方式,这种创建方式主要是利用InMemoryUserDetailsManager来实现。我们还是在上面的SecurityConfig类中,编写相应代码。

这种方式中,我们创建用户和分配密码,与第一种方式基本类似,但是密码编码器需要单独配置,通过@Bean直接生成PasswordEncoder对象即可。代码如下:

@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
   .......
       
   /**
    * 内存中创建多个用户角色的方式2:
    * 基于内存的多用户支持.在内存中创建多个用户与角色.
    */
    @Bean
    public UserDetailsService createUserDetailService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
 
        //在内存中创建admin与user用户
        manager.createUser(User.withUsername("admin").password("123").roles("ADMIN", "USER").build());
        manager.createUser(User.withUsername("user").password("123").roles("USER").build());
        return manager;
    }
 
    /**
    * 由于5.x版本之后默认启用了委派密码编码器,因而按照以往的方式设置内存密码将会读取异常,所在需要暂时将密码编码器设置为NoOpPasswordEncoder.
    * 后面我们可以修改成BCryptPasswordEncoder.
    * 这里必须设置一个密码编码器,否则无法通过对用户名和密码的验证.
    */
    @Bean
    public PasswordEncoder passwordEncoder() {
        //return new BCryptPasswordEncoder();
        return NoOpPasswordEncoder.getInstance();
    }      
       
   .......     
    
}

InMemoryUserDetailsManager是UserDetailsService接口中的一个实现类,InMemoryUserDetailsManager的类结构图如下:
在这里插入图片描述
它可以把用户数据保存在内存中,在一些不需要引入数据库的场景下很有用,也就是如果我们不想持久化保存用户角色信息,用InMemoryUserDetailsManager类的createUser()方法生成用户,并赋予相应的角色即可。

五.验证

项目启动起来,然后以不同的身份登录进来,分别访问不同的接口,当某个用户在不具备相应角色时,会出现403提示信息。只有具有相应的角色权限时,才可以访问对应的接口。截图如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/611976.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第二十二章行为型模式—备忘录模式

文章目录 备忘录模式解决的问题结构实例“白箱” 备忘录模式“黑箱” 备忘录模式 存在的问题适用场景 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法与对象间职责的分…

【QQ聊天界面、创建模型、懒加载数据 Objective-C语言】

一、今天我们要做的就是这个案例 1.我们今天要做的案例,做好了之后的效果就是这样 这个案例,和昨天那个微博的案例是非常相像的, 哪些相像呢, 1)整体是不是也是能滚动啊, 2)能滚动,它不仅仅是一个UIScrollView 它里面,这个也是一行、两行、三行、四行、 所以说,…

Java核心知识点常考面试题(持续更新中)

Java核心知识点常考面试题(持续更新中) 线程与线程池Java锁机制轻量级锁重量级锁 线程与线程池 一、线程 1、线程的状态 2、线程的创建方式 (1)继承 Thread 类; (2)实现 Runnable 接口&#…

大学计算机专业 学习Python学习路线图(最新版)

这是我刚开始学习python时的一套学习路线,从入门到上手。(不敢说精通,哈哈~) 希望对大家有帮助哈~ 大家需要高清得完整python学习路线可以 一、Python入门、环境搭建、变量、数据类型 二、数据库编程 三、Linux系统 四、网页编…

工信部—高级软件开发工程师认证

工业和信息化部教育与考试中心是工业和信息化部直属事业单位,承担计算机技术与软件专业技术资格考试、通信专业技术人员职业水平考试、电子通信行业职业技能鉴定、全国信息技术人才培养工程、产业工人网络平台建设等人才培养选拔工作。 软件工程师(Software Enginee…

京东数据分析软件工具(京东618销量查询)

这一期,我们主要分享今年618京东美妆的预售数据,包括面部护肤、香水彩妆、男士面部护肤品类。 -面部护肤- 今年618,面部护肤品类在京东累计预售量达到130万件,预售额达到13亿元。预售期间,护肤品类均价在1010元左右。期…

计算机中丢失VCRUNTIME140_1怎么办,vcruntime140_1.dll的三个修复方法

vcruntime140_1.dll是一个Windows系统文件,它是Microsoft Visual C Redistributable for Visual Studio 2019软件包的一部分,用于运行使用Visual C开发的应用程序。在我们打开软件或者游戏的时候,提示计算机中丢失VCRUNTIME140_1怎么办&#…

刷完它,最少17K,真的不能再少了····

金3银4已经过去了,金9银10也快来了,你找到工作了吗?薪资多少k?8K?13K?17? 最近有不少小伙伴在后台给我留言,说最近准备面试了,但是不知道从何下手! 既然大家…

鲁大师5月新机性能/流畅/久用榜:蓝绿厂霸榜,天玑9200+与高通骁龙8 Gen2迎来首次交锋

性能榜 6.18年中购物节前夕,一众厂商开始扎堆发布新机冲销量,也导致本月的新发机型数量达到了19款。 从品牌来看,ov两家和其子品牌、独立品牌就占据了十二台。从机型定位来看,本月的手机竞争主要围绕中端市场,除了索尼…

【Log】大三的最后一个项目,所以我到底是不是恋爱脑?

文章目录 梦开始的地方核心功能恋爱相册(LoveAlbum)恋爱日志(LoveLogs)爱情邮局(LovePostOffice)时间线(TimeLine)待办列表(LoveList) 技术栈 梦开始的地方 …

STM32单片机WIFI智能语音家居窗户窗帘空调灯控制系统OLED显示

实践制作DIY- GC0139-WIFI智能语音家居窗户窗帘空调灯控制系统 基于STM32单片机设计---WIFI智能语音家居窗户窗帘空调灯控制系统 二、功能介绍: 件组成:stm32103 系列单片机,OLED 显示屏模块,语音识别模块,DTH11温湿度…

掌握了这些技术后,才发现进大厂,也没有那么难...

为了帮助大家快速回顾学习软件测试中的知识点:这套学习笔记,面试手册是由多位一线大牛老师联手打造3个月制作而成,几乎涵盖了所有的软件测试技术栈。掌握它们才发现进大厂,也没有那么难 全网首发!非常珍贵&#xff0c…

控制算法工程师的工作职责(合集)

控制算法工程师的工作职责1 职责: 1、准确地控制密闭容器的气体或液体的压力,以供校准其他压力表使用; 2、准确地控制温度场的精度,以供校准其他温度计使用; 3、根据不同的控制方案和执行机构/加热制冷方式;测试其特性、建立数学模型、设计算…

运维小白必学篇之基础篇第十五集:FTP实验

FTP实验 实验者:胡 阳 匿名用户验证: 例:(前提配置,防火墙关闭,yum安装,同模式vmware11) 现有一台计算机huyanggw(视作服务端),IP地址为192.1…

仙境传说RO:添加商店物品教程

仙境传说RO:添加商店物品教程 我是艾西,今天跟大家分享下仙境传说RO游戏中我们自己怎么创建商店卖东西装备等,首先看看下图以及自己创建商店时需要在文档里创建的脚本格式 //*------------------shop普通商店------------------ //带坐标的…

介绍如何使用反向传播的 CNN 接受场计算以及代码讲解

在上一篇文章中,我们学习了如何对任意大小的图像进行分类并可视化网络的响应图。 图 1:“骆驼”类激活的边界框。 在图 1 中,请注意骆驼的头部几乎没有突出显示,响应贴图包含大量沙子纹理。边界框也明显关闭。 有些事情是不对的。 我们使用的 ResNet18 网络非常准确,实…

win11系统内存完整性不兼容驱动程序查找删除教程

近期很多用户都对进行了升级更新,但是出现了很多不兼容的情况,导致内存完整性关闭了,想要开启就需要删除不兼容的驱动程序,关于这个问题,我就来分享查找和删除的方法,希望能够帮助到更多的用户。 当您考虑…

数字工厂解决方案,先进的数字工厂怎么建立?

2023年5月23日,国家市场监督管理总局(国家标准化管理委员会)发布2023年第2号中华人民共和国国家标准公告:批准GB/T 42562-2023《工业互联网平台选型要求》;GB/T 42568-2023《工业互联网平台微服务参考框架》&#xff1…

白盒测试、黑盒测试、灰盒测试

根据被测对象的不同,软件测试可以分为白盒测试、黑盒测试、灰盒测试三种方式。那么,这三种测试测试方式具体是如何运行的?各有什么特点?下面,跟着小厚一起了解一下吧! 01 白盒测试 ●概念: ➢…

网络安全入门必学内容

随着时代的发展,经济、社会、生产、生活越来越依赖网络。而随着万物互联的物联网技术的兴起,线上线下已经打通,虚拟世界和现实世界的边界正变得模糊。这使得来自网络空间的攻击能够穿透虚拟世界的边界,直接影响现实世界的安全。 网…