【SpringBoot3】Spring Security 常用注解

注:本文基于Spring Boot 3.2.1 以及 Spring Security 6.2.1

Spring Security 6 的常用注解包括以下几种,通过这些注解可以更加方便的控制资源权限。

  • @Secured :方法执行前检查,直接判断有没有对应的角色
  • @PreAuthorize:方法执行前检查,根据SpEL表达式执行结果判断是否授权
  • @PostAuthorize:方法执行后检查,根据SpEL表达式执行结果判断是否授权

要使用以前注解必须增加配置,开启校验功能

// 用于启用方法级别的安全支持
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)

@Secured

方法执行前检查,直接判断有没有对应的角色

示例代码:

@Secured({ "ROLE_USER" })
public void create(Contact contact);

@Secured({ "ROLE_USER", "ROLE_ADMIN" })
public void update(Contact contact);

@Secured({ "ROLE_ADMIN" })
public void delete(Contact contact);

@PreAuthorize

方法执行前检查,根据SpEL表达式执行结果判断是否授权

示例代码:

// 有角色
@PreAuthorize("hasRole('ROLE_ADMIN')")
// 有任一角色
@PreAuthorize("hasAnyRole({'ROLE_USER','ROLE_ADMIN'})")
// 有任一权限
@PreAuthorize("hasAnyAuthority({'user:search','user:edit'})")

其他用法

@PreAuthorize 参数是SpEL表达式,所以还可以有其他用法

1、方法参数值判断,@PreAuthorize("#age>10")

@GetMapping("/age")
@PreAuthorize("#age>10")
public String age(Integer age) {
    return "Hello age "+ age;
}

2、调用bean的方法判断

1)创建Bean,判断是否有权限

@Component("au")
public class AuthUtils {

    public boolean check(String role) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .noneMatch(role::equals)) {
            throw new AccessDeniedException("User does not have the required permission");
        }
        return true;
    }
}

2)在方法上使用,@PreAuthorize("@au.check('ROLE_USER')")

@GetMapping("/user_au")
@PreAuthorize("@au.check('ROLE_USER')")
public String user_au() {
    return "Hello user_au";
}

@PreAuthorize配合使用的方法定义在 org.springframework.security.access.expression.SecurityExpressionOperations

在这里插入图片描述

完整代码示例

1、HttpSecurity 配置

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class BasicSecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests((authorize) -> authorize
                        // 放行登录页面
                        .requestMatchers("/login").permitAll()
                        // 拦截其他所有请求
                        .anyRequest().authenticated()
                )
                // 退出时,让session失效
                .logout(logout -> logout.invalidateHttpSession(true))
                // 配置登录页面 和 登录成功后页面
                .formLogin(form -> form.loginPage("/login").permitAll()
                        .loginProcessingUrl("/login").defaultSuccessUrl("/index"));
        http.exceptionHandling(e->e.accessDeniedPage("/noAuth"));
        // 开启csrf 保护
        http.csrf(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user1 = User.withUsername("admin").password("{noop}123456").roles("ADMIN").build();
        UserDetails user2 = User.withUsername("user").password("{noop}123456").authorities("user:edit","ROLE_USER").build();
        return new InMemoryUserDetailsManager(user1,user2);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

}

2、测试controller类,DemoController

import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @GetMapping("/admin")
    @Secured({"ROLE_ADMIN"})
    public String admin() {
        return "Hello admin";
    }

    @GetMapping("/user")
    @Secured({"ROLE_ADMIN","ROLE_USER"})
    public String user() {
        return "Hello user";
    }

    @GetMapping("/admin2")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public String admin2() {
        return "Hello admin";
    }
    @GetMapping("/user2")
    @PreAuthorize("hasAnyRole({'ROLE_USER','ROLE_ADMIN'})")
    public String user2() {
        return "Hello user";
    }

    @GetMapping("/user_perm")
    @PreAuthorize("hasAnyAuthority({'user:search','user:edit'})")
    public String user_perm() {
        return "Hello user";
    }
    @GetMapping("/user_au")
    @PreAuthorize("@au.check('ROLE_USER')")
    public String user_au() {
        return "Hello user_au";
    }
    @GetMapping("/age")
    @PreAuthorize("#age>10")
    public String age(Integer age) {
        return "Hello age "+ age;
    }

    @RequestMapping("/all")
    public String all() {
        return "Hello all";
    }

}

如果需要自定义认证和授权逻辑,可以实现 UserDetailsService 和 AuthenticationProvider 接口,并在配置类中注入这些自定义的 Bean。

这就是 Spring Security 的注解验证流程。通过合理地使用注解和配置类,可以轻松地实现基于角色的访问控制、方法级别的授权等安全功能。同时,Spring Security 还提供了丰富的扩展点,允许开发者根据具体需求进行定制。

Spring Security 常见扩展点

Spring Security 提供了许多扩展点,允许开发者根据具体需求进行定制和扩展。以下是一些常见的扩展点:

  1. 过滤器链(Filter Chain)
    Spring Security 本质是一个过滤器链,开发者可以通过自定义过滤器来扩展其功能。例如,可以添加自定义的认证过滤器、授权过滤器或会话管理过滤器等。

  2. 认证机制(Authentication Mechanism)
    可以自定义认证机制,包括用户信息的加载、密码的编码和校验等。通过实现 AuthenticationProvider 接口,可以定义自己的认证逻辑。

  3. 授权决策(Authorization Decision)
    开发者可以通过实现 AccessDecisionManager 接口来自定义授权决策逻辑。这允许你根据业务逻辑来定制权限判断。

  4. 用户服务(User Service)
    通过实现 UserDetailsService 接口,可以自定义用户信息的加载方式。例如,你可以从数据库、LDAP 服务器或其他数据源中获取用户信息。

  5. 安全事件监听(Security Event Listeners)
    Spring Security 提供了安全事件监听器,允许你监听认证、授权等事件,并根据事件执行相应的操作。

  6. 方法安全(Method Security)
    除了使用注解外,你还可以通过配置 GlobalMethodSecurityConfiguration 来全局启用方法级别的安全支持,并自定义方法安全的配置。

  7. 安全表达式语言(Security Expression Language)
    Spring Security 使用了强大的安全表达式语言(SpEL),允许你在注解和配置中使用表达式来定义复杂的权限和角色要求。

  8. 会话管理(Session Management)
    可以自定义会话的创建、存储、失效等逻辑,以满足特定的业务需求。

  9. HTTP 安全配置(HTTP Security Configuration)
    通过重写 configure(HttpSecurity http) 方法,你可以自定义 HTTP 安全配置,包括 CSRF 保护、点击劫持保护、缓存控制等。

  10. 异常处理(Exception Handling)
    可以自定义认证和授权失败时的异常处理逻辑,例如返回自定义的错误页面或错误信息。

这些扩展点使得 Spring Security 非常灵活,能够适应各种不同的安全需求。通过合理利用这些扩展点,开发者可以构建出强大而安全的应用程序。

参考

  • https://docs.spring.io/spring-security/reference/index.html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt C++春晚刘谦魔术约瑟夫环问题的模拟程序

什么是约瑟夫环问题? 约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N6,M5,被杀掉的顺序是:5&#xff…

tkinter做一个秒表

文章目录 需求和框架布局和主流程计时函数 需求和框架 本文试图实现一个简单的秒表,内容如下 这个软件非常简单,其UI元素只有一个文字标签外加三个按钮,这三个按钮的功能如下 点击Start按钮,开始进行计时,同时Start变…

已解决:IDEA中@Autowired自动注入MyBatis Mapper报红警告的几种解决方法

今天在使用 IDEA 使用 MyBatis 的时候遇到了这种情况: 可以看到 userMapper 下有个红色的波浪警告,虽然代码没有任何问题,能正常运行,但是这个红色警告在这里杵着确实让人很窝心。 于是我在网上找了找,最终明白了原因…

【鸿蒙系统学习笔记】状态管理

一、介绍 资料来自官网:文档中心 在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状…

电脑提醒待办事项:高效、快捷、更科学的方法

在这个快节奏的社会里,我常常感到时间不够用,仿佛一天24小时根本不够我分配。每天都有一大堆待办事项等着我,但总是有这样那样的事情让我分心,导致我经常忘记一些重要的任务。 每次当我想起那些被遗忘的待办事项时,都…

本地创建Git仓库

在 Windows 下,可以通过以下步骤在本地创建一个 并模拟远程Git 仓库。 1、在命令行中打开模拟远程Git 仓库目标文件夹: 打开命令提示符或 PowerShell。例如: 创建裸仓库(模拟远程仓库):创建一个裸仓库&am…

亚马逊、沃尔玛、eBay等跨境平台自养号测评的风险和技术解析

亚马逊等平台延伸至世界各地,竞争激烈。许多卖家使用自养号测评来提高产品排名和销量。但自养号测评技术存在一定的技术局限性,很多卖家的账号因对自养号原理和底层环境搭建缺乏了解很多卖家的账号被关联封禁。本文将为您揭示自养号测评的风险&#xff0…

【小呆的力学笔记】弹塑性力学的初步认知四:简单应力状态下的应力应变关系

文章目录 2. 简单应力状态下的应力应变关系2.1 简单拉伸的应力应变关系2.2 真实应力应变关系2.3 应力-应变关系简化模型 2. 简单应力状态下的应力应变关系 我们在高中就学过,弹簧拉伸力和变形量成比例,对于一般的金属材料,在一定载荷以内这种…

Cadence Allegro PCB设计88问解析(三十三) 之 Allegro 中 Quick Reports的使用

一个学习信号完整性仿真的layout工程师 在进行PCB设计时,经常会查看一下整个PCB的基本信息,比如器件个数,网络数量、pin的数量。尤其在投板的时候还要查看下Dangling Lines、Dangling Vias等。还有其他的关于shape、via、走线、钻孔等等相关信…

顶顶通实时质检系统如何添加词库

文章目录 前言联系我们步骤1. 导入系统预置词库2. 手动添加词库 在实时质检时如何质检到词库 前言 本篇文章主要讲解顶顶通实时质检系统如何添加词库。 词库添加的方式: 导入系统预置词库手动添加词库 联系我们 有意向了解实时质检系统的用户,可以点击…

Photoshop 2023(Ps)下载安装及详细安装教程

Photoshop(Ps)的介绍 Adobe Photoshop,简称“PS”,是由AdobeSystems开发和发行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具,可以有效地进行图片编辑和创造工作。PS有很多功能,在图像、…

grafana配置钉钉告警模版(一)

1、配置钉钉告警模版 创建钉钉告警模版,然后在创建钉钉告警时调用模版。 定义发送内容具体代码 my_text_alert_list 是模版名称后面再配置钉钉告警时需要调用。 {{/* 定义消息体片段 */}} {{ define "my_text_alert_list" }}{{ range . }}告警名称&…

术业有专攻!三防加固平板助力工业起飞

在日常使用中的商业电脑比较追求时效性,以市场定位做标准,内部元件只需满足一般要求就行,使用寿命比较短。而三防平板电脑是主要运用在复杂、恶劣的环境下所以在需求方面较高,需要保证产品在恶劣条件下正常使用,满足行业领域的需求…

springboot746旧物置换网站

springboot746旧物置换网站 获取源码——》公主号:计算机专业毕设大全

二维码钓鱼激增587%:用户陷入社交诈骗陷阱!

Check Point软件技术公司发布的新研究揭示了典型的QR码攻击,通过Check Point的实时网络威胁地图,在两周内发现了2万起QR码钓鱼和恶意软件攻击事件,突显了QR码在网络犯罪分子面前的脆弱性。 QR码是"Quick Response Code"&#xff08…

minio+nginx 集群快速搭建

文章目录 1、概要2、整体架构流程3、集群搭建3.1、服务器准备3.2、下载并安装3.3、minio集群配置3.4、minio.service配置3.5、启动 4、nginx 转发 1、概要 minIO 是一个开源的分布式对象存储服务,可用于构建高可用性和高扩展性的存储集群。 分布式架构:…

SpringSecurity + OAuth2 详解

SpringSecurity入门到精通 ************************************************************************** SpringSecurity 介绍 **************************************************************************一、入门1.简介与选择2.入门案例-默认的登录和登出接口3.登录经过了…

CSS SVG技术制作的复杂多层发光星形加载动画组件

<template><!-- 定义一个视图容器,用于展示加载动画 --><view class="loader"><svg viewBox="0 0 128 128" height="128" width="128" class="star"><defs><filter id="star-glow&q…

Windows下用CMake编译ITK及配置测试

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 ITK是什么&#xff1f; ITK&#xff08; Insight Segmentation and Registration Toolkit&#xff09;是美国国家卫生院下属的国…

MBD_入门篇_18_Simulink查表模块

18.Simulink查表模块 18.1 概述 LookUpTable&#xff0c;查表模块。比较常用的模块&#xff0c;参数较多&#xff0c;会复杂一点&#xff0c;比较重要的模块&#xff0c;一定掌握。 18.2 n-DLookUpTable N维查表模块 18.2.1 查表原理 通过有限的数据去得出相关的结果。比如我们…