【SpringBoot3】Spring Security 常用注解

news2025/1/16 15:58:42

注:本文基于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

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

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

相关文章

Jmeter实现阶梯式线程增加的压测

安装相应jmeter 插件 1:安装jmeter 管理插件: 下载地址:https://jmeter-plugins.org/install/Install/,将下载下来的jar包放到jmeter文件夹下的lib/ext路径下,然后重启jmeter。 2:接着打开 选项-Plugins Ma…

【FastAPI】P3 请求与响应

目录 请求路径参数查询参数 响应JSON 响应文本响应返回 Pydantic 模型 在网络通讯中,请求(Request) 与 响应(Response) 扮演着至关重要的角色,它们构成了客户端与服务器间互动的根本理念。 请求&#xff0…

PMP考完之后考什么,NPDP值得考吗?

PMP考完之后可以考虑考一个NPDP证书,从事新产品开发相关工作的学习下NPDP是很有必要的~参与新产品开发相关的中高层管理人员,产品团队成员等非常适合学习NPDP。 一、什么是NPDP? NPDP 是产品经理国际资格认证,美国产品开发与管理…

【MySQL初阶】索引

1. 索引基本概念 1.1 索引介绍 索引(index):是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或者多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。(具体细节在MySQL进阶章节详…

如何使用IP代理解决亚马逊账号IP关联问题?

亚马逊账号IP关联问题是指当同一个IP地址下有多个亚马逊账号进行活动时,亚马逊会将它们关联在一起,从而可能导致账号被封禁或限制。 为了避免这种情况,许多人选择使用IP代理。 IP代理为什么可以解决亚马逊IP关联问题? IP代理是…

3d模型渲染了是白色的什么原因?怎么解决?--模大狮模型网

3D模型渲染成白色的原因可能有几种情况: 一:材质设置问题 检查模型的材质设置,确保正确指定了颜色或纹理。有时候,默认的材质颜色可能是白色,您可以尝试修改材质属性来改变渲染结果。 二:光照设置问题 检…

点餐|外卖订餐小程序|基于微信小程序的外卖订餐系统设计与实现(源码+数据库+文档)

点餐|外卖订餐小程序目录 目录 基于微信小程序的外卖订餐系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户微信端功能模块 2、管理员服务端功能模块 3、商家务端功能模块 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设…

【Java多线程】线程安全问题与解决方案

目录 1、线程安全问题 1.2、线程安全原因 2、线程加锁 2.1、synchronized 关键字 2.2、完善代码 2.3、对同一个线程的加锁操作 3、内容补充 3.1、内存可见性问题 3.2、指令重排序问题 3.3、解决方法 3.4、总结 volatile 关键字 1、线程安全问题 某个代码&#xff…

雷卯有多种封装3.3V的ESD DIODE供您选择

一.3.3V ESD型号如下 二.多种多路封装 三.3.3V保护方案 方案优点:用于满足IC VCC 3.3V的静电浪涌保护,根据电源所处环境选择合适保护电流的ESD器件;高速传输接口选择超低电容ULC0511CDN,保证信…

友点CMS GetSpecial SQL注入漏洞复现

0x01 产品简介 友点CMS是一款高效且灵活的网站管理系统,它为用户提供了简单易用的界面和丰富的功能。无论是企业还是个人,都能通过友点CMS快速搭建出专业且美观的网站。该系统支持多种内容类型和自定义模板,方便用户按需调整。同时,它具备强大的SEO功能,能提升网站在搜索…

高并发系统中常见的问题

在当今的高并发系统中,常见的问题是多种多样的,这些问题往往会对系统的稳定性和性能产生重大影响。本文将详细介绍高并发系统中常见的问题,并探讨其产生原因和解决方案。 一、高并发系统概述 高并发系统是指在同一时间内有大量用户同时访问…

Sui在Dacade推出Move课程,完成学习奖励SUI

Dacade推出了一门Sui开发者课程,通过一系列引人入胜的挑战,为开发者提供了一个沉浸式的Move技术之旅。在这门课程中,Dacade的教育材料将引导用户利用Sui强大的DeFi原生功能(包括DeepBook和zkLogin)构建DeFi应用。此外&…

Tofu5m 高速实时推理Yolov8

Tofu5m 是高性价比目标识别跟踪模块,支持可见光视频或红外网络视频的输入,支持视频下的多类型物体检测、识别、跟踪等功能。 实测视频链接:Tofu5m识别跟踪模块_哔哩哔哩_bilibili 产品支持视频编码、设备管理、目标检测、深度学习识别、跟踪…

c++类和对象新手保姆级上手教学(中)

前言: 类和对象中篇,这里讲到的前4个默认成员函数,是类和对象中的重难点,许多资料上的讲法都非常抽象,难以理解,所以我作出这篇总结,分享学习经验,以便日后复习。 目录 6个默认成员…

基于uniapp微信小程序的汽车租赁预约系统

随着现代汽车租赁管理的快速发展,可以说汽车租赁管理已经逐渐成为现代汽车租赁管理过程中最为重要的部分之一。但是一直以来我国传统的汽车租赁管理并没有建立一套完善的行之有效的汽车租赁管理系统,传统的汽车租赁管理已经无法适应高速发展,…

【lesson59】线程池问题解答和读者写者问题

文章目录 线程池问题解答什么是单例模式什么是设计模式单例模式的特点饿汉和懒汉模式的理解STL中的容器是否是线程安全的?智能指针是否是线程安全的?其他常见的各种锁 读者写者问题 线程池问题解答 什么是单例模式 单例模式是一种 “经典的, 常用的, 常考的” 设…

MySQL多实例部署:从概念到实操的全面指南

目录 MySQL多实例管理 单实例 什么是多实例 多实例的好处 多实例的弊端 MySQL多实例用在哪些场景 资金紧张的公司 用户并发访问量不大的业务 大型网站也有用多实例 部署MySQL多实例 rpm和源码的优缺点 二进制方式安装mysql 准备二进制mysql运行所需的环境 准备多…

ENG-2 AM,绿色钠离子探针,能够与常用的显微镜和光谱仪兼容

文章关键词:ENG-2 AM,钠离子荧光探针ENG-2,绿色钠离子探针 一、基本信息 产品简介:Enhanced NaTrium Green-2 AM (ENG-2 AM) 是一种新型的钠离子(Na)荧光探针,它作为 Asante NaTrium Green-2 …

[Bug解决] Invalid bound statement (not found)出现原因和解决方法

1、问题描述 在写了一个很普通的查询语句之后,出现了下面的报错信息 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.oauth.mapper.WxVisitorQrBeanMapper.selectByComIdAndEmpId at org.apache.ibatis.binding.Mappe…

力扣日记2.20-【回溯算法篇】491. 非递减子序列

力扣日记:【回溯算法篇】491. 非递减子序列 日期:2023.2.20 参考:代码随想录、力扣 ps:放了个寒假,日记又搁置了三星期……(下跪忏悔) 491. 非递减子序列 题目描述 难度:中等 给你一…