Spring Boot下Spring Security权限认证@PreAuthorize注解失效

Spring Boot下Spring Security权限认证@PreAuthorize注解失效

根据我的经历,一共有三种情况。如果谁还遇到其他情况可以提出来。

第一种情况。

就是网上大量出现的。没有添加 @EnableGlobalMethodSecurity 注解。
还有 @EnableGlobalMethodSecurity 注解只能添加在继承了WebSecurityConfigurerAdapter
的类上面。

package com.jiang.login.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * SecurityConfig  登录认证的配置
 *
 * @创建人 江枫沐雪
 * @创建时间 2021/7/16 9:09
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("myUserDetailsService")
    private UserDetailsService userDetailsService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    //查询用户信息
    @Override
    protected void configure(AuthenticationManagerBuilder  auth) throws Exception {
        //用户详情信息
        auth.userDetailsService(userDetailsService)
                //密码加密方式
                .passwordEncoder(bCryptPasswordEncoder);
    }

    //安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                //配置跨域请求 并且 关闭打开的csrf保护
                .cors().and()
                .csrf().disable()
//                 认证配置
                .authorizeRequests()
//                 登录验证等放行
                    .antMatchers("/auth/**","/app/**").permitAll()
//                    .antMatchers("/per/get").hasAuthority("GET_PER")
//                    .antMatchers("/per/getPer").hasAuthority("GET_PER")
//                    .antMatchers("/per/getPer").access("hasRole('ROlE_GET')")
//                 剩下的接口都需要登陆后访问
                    .anyRequest().authenticated()
                    .and()
                //表单登录
                .formLogin()
//                   用户未登录的的时候跳转的这个路径
                    .loginPage("/home")
//                   用户登录时,用户名、密码提交的目的路径
                    .loginProcessingUrl("/login")
//                   用户成功登录以后
                    .successForwardUrl("/success")
                    .and()
                .logout()
                    .logoutUrl("/logout");
//                    .logoutSuccessUrl("/log")
    }
}

第二种情况

就是,你的 @PreAuthorize 注解使用的角色授权,不是资源(权限)授权。

@PreAuthorize(“hasRole(‘USER’)”)

因为你使用的是角色授权,所以Spring Security会自动在你设置的参数前加上一个ROLE_,那么你在添加角色权限的时候传递的差数是ROLE_USER
例如:

UserDetails userDetails = User.withUsername(user.getUsername())
                .password(user.getPassword()).roles("ROLE_USER");

第三种情况

这是我遇见非常诡异的情况。
@PreAuthorize(“hasAuthority(‘GET_PER’)”) 不能生效。

首先我创建了一个LoginController的controller文件,然后在创建了一个测试接口

/**
 * Lonig
 *
 * @创建人 江枫沐雪
 * @创建时间 2021/7/26 14:37
 */
@RestController
public class LoginController {

    @PostMapping("/per/get")
    @PreAuthorize("hasAuthority('GET_PER')")
    private String getPerm(){
        return "拥有权限!";
    }
    
}

但这个测试接口无论如何都无法拦截,但我使用web方法授权就可以。
我调了几个小时,依然没有解决。
但神奇的事情来了。
我又创建了一个controller类RoleController 在他下面重新写了一个普通的查询方法,竟然可以拦截。
于是,我就又在RoleController重新写了一个普通的测试接口,结果成功拦击。
o((⊙﹏⊙))o
当时,我已经懵了!!!
最后,我想是不是我LoginController有问题,我就把LoginController中的方法粘贴复制了过来,发现不能拦截!!!

@RestController
@RequestMapping("role")
public class RoleController {

    @Autowired
    private RoleService roleService;

	//
    @GetMapping("get")
    @PreAuthorize("hasAuthority('GET_ROLE')")
   public ApiResponse getRole(){
        return ApiResponseWithData.ofSuccess(roleService.getRole());
    }

	//
    @GetMapping("permin")
    @PreAuthorize("hasAuthority('GET_PERMIN')")
    public string getPerMin(){
        return "真的好神奇!";
    }

    //从LoginController中粘贴复制过了,但依然不能拦截
    @PostMapping("/per")
    @PreAuthorize("hasAuthority('GET_PER')")
    private string getPer(){
        return "拥有权限!";
    }
}

最后,我放弃寻找原因,因为其他的都可以权限控制。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
Spring Boot中,@PreAuthorize注解是用于在方法执行之前进行权限验证的。如果你不想使用@PreAuthorize注解,你可以通过其他方式来实现权限验证。 一种常见的方式是使用Spring Security框架来进行权限验证。Spring Security提供了一套完整的安全认证和授权机制,可以轻松地集成到Spring Boot应用中。 首先,你需要在pom.xml文件中添加Spring Security的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 然后,在你的应用主类上添加@EnableWebSecurity注解,启用Spring Security的功能: ```java import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @EnableWebSecurity public class YourApplication { // ... } ``` 接下来,你可以创建一个继承自WebSecurityConfigurerAdapter的配置类,来配置权限验证规则: ```java import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyRole("ADMIN", "USER") .anyRequest().authenticated() .and() .formLogin(); } } ``` 上述配置中,我们定义了两个URL模式的权限规则:/admin/**需要具有ADMIN角色才能访问,/user/**需要具有ADMIN或USER角色才能访问。其他URL需要进行身份验证。 当你使用Spring Security进行权限验证时,你可以在方法中使用注解来进行更细粒度的权限控制,例如@Secured、@RolesAllowed等。 除了Spring Security,你还可以使用其他的权限验证框架或自定义实现来替代@PreAuthorize注解。这些方式的具体实现方式会根据你的需求和项目架构而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值