详细分析SpringSecurity中的@PreAuthorize注解

2024-06-04 4147阅读

目录

  • 1. 基本知识
  • 2. 使用方式
    • 2.1 配置类
    • 2.2 直接使用

      1. 基本知识

      在Java中,@PreAuthorize 是Spring Security框架中的一个注解,用于在方法调用之前对用户的权限进行验证。

      允许在方法级别定义访问控制规则,确保只有满足指定条件的用户才能调用该方法

      这个注解通常与Spring的AOP(面向切面编程)结合使用,推荐阅读:

      1. Spring框架从入门到学精(全)
      2. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)

      本身的作用主要如下:

      • 权限控制: 主要用于实现基于方法调用的权限控制,确保只有经过验证的用户才能访问受保护的方法
      • 条件判断: 允许在注解中定义条件表达式,这些表达式决定是否允许方法调用

        使用方式:

        @PreAuthorize 注解的参数是一个 SpEL(Spring Expression Language)表达式,用于定义权限规则(SpEL支持在表达式中使用各种功能,包括方法调用、条件判断等)

        表达式的结果应该是布尔值,如果为 true,则允许方法调用,否则抛出权限异常。

        示例:@PreAuthorize("hasRole('ROLE_ADMIN')") 表示只有具有 ROLE_ADMIN 角色的用户可以调用该方法。

        除了在方法级别使用 @PreAuthorize,还可以在全局配置中定义方法安全性

        通过配置类,指定应用于整个应用程序的全局安全性规则。

        2. 使用方式

        要么以配置类要么直接使用

        2.1 配置类

        如果通过配置类的方式:

        一般通过继承 WebSecurityConfigurerAdapter 类,通过这个类配置应用程序的安全性

        大致的Demo如下:

        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
        import org.springframework.security.config.annotation.web.builders.HttpSecurity;
        import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
        import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
        @Configuration
        @EnableWebSecurity
        public class SecurityConfig extends WebSecurityConfigurerAdapter {
            // 配置内存中的用户
            @Override
            protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.inMemoryAuthentication()
                    .withUser("user").password("{noop}password").roles("USER")
                    .and()
                    .withUser("admin").password("{noop}admin").roles("ADMIN");
            }
            // 配置访问控制规则
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http
                    .authorizeRequests()
                        .antMatchers("/admin/**").hasRole("ADMIN")
                        .antMatchers("/user/**").hasRole("USER")
                        .anyRequest().authenticated()
                        .and()
                    .formLogin()
                        .loginPage("/login")
                        .permitAll()
                        .and()
                    .logout()
                        .permitAll();
            }
        }
        

        一个是普通用户,一个是管理员。

        访问控制规则指定了 /admin/** 路径需要具有 “ADMIN” 角色的用户才能访问

        /user/** 路径需要具有 “USER” 角色的用户才能访问

        其他请求需要身份验证。登录页面配置为 /login,注销行为允许所有用户。

        整体对于配置类来说:

        1. 定义认证规则: 指定用户认证的规则、设置用户的身份验证方式,例如基于内存、数据库、LDAP 等方式,并定义用户的角色和权限

        2. 配置访问控制规则:哪些路径需要身份验证,哪些路径允许匿名访问,哪些路径需要特定的角色或权限

        3. 定制登录和注销行为: 自定义登录页面、处理登录请求的 URL、注销行为等

        4. 启用或禁用特定的安全性功能: 启用或禁用各种安全性功能,例如 CSRF 保护、Session 管理等

        2.2 直接使用

        内部内置的方法,都在这个类上:

        @PreAuthorize 注解内置了一些方便的方法,可以直接在表达式中使用,例如:

        • hasRole('ROLE_NAME') 检查用户是否具有指定角色。
        • hasAnyRole('ROLE1', 'ROLE2') 检查用户是否具有给定角色中的任意一个。
        • hasAuthority('AUTHORITY_NAME') 检查用户是否具有指定权限。
        • hasAnyAuthority('AUTHORITY1', 'AUTHORITY2') 检查用户是否具有给定权限中的任意一个。
        • hasPermission(targetObject, 'permission'): 检查用户是否具有特定对象的特定权限。

          如图所示:

          详细分析SpringSecurity中的@PreAuthorize注解 第1张

          对于上述方法的基本细节操作如下:

          方法参数传递:

          在表达式中,可以引用方法的参数,例如:

          @PreAuthorize("hasPermission(#entity, 'read')") 表示检查用户是否有对给定实体的读权限。

          逻辑运算:

          表达式支持逻辑运算符,如 and, or, not,允许构建更复杂的权限规则

          @PreAuthorize("hasRole('ADMIN') and hasPermission(#entity, 'write')")
          

          大致Demo如下:

          import org.springframework.security.access.prepost.PreAuthorize;
          public class MyService {
              // 示例1: 仅允许具有ROLE_ADMIN角色的用户调用
              @PreAuthorize("hasRole('ROLE_ADMIN')")
              public void adminOperation() {
                  // 实现管理员操作的代码
              }
              // 示例2: 允许具有READ权限并且是特定用户的调用
              @PreAuthorize("hasPermission(#username, 'READ')")
              public void userOperation(String username) {
                  // 实现用户操作的代码
              }
          }
          

          @PreAuthorize 注解用于控制方法的访问权限。

          • 只有具有ROLE_ADMIN角色的用户才能调用adminOperation方法
          • 只有具有READ权限并且传入的用户名符合条件的用户才能调用userOperation方法

    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]