【问题标题】:Spring Preauthorized works but HTTPSecurity possibly being ignored?Spring Preauthorized 有效但 HTTPSecurity 可能被忽略?
【发布时间】:2021-06-03 19:10:16
【问题描述】:

我在我的 Spring Boot 应用程序中使用 OpenId 和 Spring Boot Security 进行了安全设置。

我无意中忘记在我的@PreAuthorize("hasAnyRole('...)") 标签中添加角色类型,并尝试以USER 进行调用,但被拒绝 (403),但我的 securityConfig 文件中确实有 hasAnyRole。一旦我将角色添加到 preAuth 标签它就起作用了,但我想知道这是否是预期的行为?还是我在安全配置文件中做错了什么?

我正在使用以下 Spring Boot 安全设置

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.2.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-openid</artifactId>
        </dependency>

网络安全文件

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private JdbcOidcBearerTokenFilter filter;

    @Autowired
    public WebSecurityConfig(@Value("${security.oauth2.client.wellKnownUrl}") String wellKnown
            , @Value("${security.oauth2.client.clientId}") String clientId
            , @Value("${security.oauth2.client.clientSecret}") String clientSecret
            , EaUserService usersService, LoginService loginService) {

        OidcService oidcService = new OidcService(wellKnown, clientId, clientSecret);
        this.filter = new JdbcOidcBearerTokenFilter(oidcService, usersService, loginService, "Authorization");
    }

    @Override
    public void configure(WebSecurity webSecurity) {
        webSecurity
                .ignoring()
                .antMatchers("/error", "/403.html");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .addFilterAfter(new OAuth2ClientContextFilter(), AbstractPreAuthenticatedProcessingFilter.class)
                .addFilterAfter(this.filter, OAuth2ClientContextFilter.class)
                .authorizeRequests()
                .antMatchers("/api/login/**", "/static/**").permitAll()   
                .antMatchers("/api/enforcementactions/**").hasAnyRole("ADMIN","DEVELOPER","USER")
    }
}

带有 PreAuth 标签的控制器 这里我一开始忘记在标签中添加'USER'并且被拒绝访问,但是上面的HttpSecurity方法中的设置不应该处理它吗?

@PreAuthorize("hasAnyRole('ADMIN','DEVELOPER','USER')")
@RestController
@RequestMapping("/api/enforcementactions")
public class EnforcementActionsController {
    
    @Autowired
    private EnforcementActionsService service;

    @GetMapping("/getallactions")
    public ResponseEntity<?> getAllEnforcementActions() {
        ... do stuff here and return data
    }

【问题讨论】:

    标签: spring-boot spring-security


    【解决方案1】:

    HttpSecurity 配置中的规则没有被忽略,它只是在@PreAuthorize 中的规则之前评估。

    角色为USER 的用户对/api/enforcementactions 的调用将首先通过Spring Security 过滤器链。
    这是将检查来自HttpSecurity 的规则的地方。
    它指出,如果用户具有以下任何角色 "ADMIN""DEVELOPER""USER",那么他们可以继续。
    有问题的用户拥有"USER" 角色,因此请求会沿过滤器链向下继续。

    一旦请求通过了过滤器链,那么@PreAuthorize 中的规则将在调用控制器方法之前被检查。
    这条规则规定只有角色"ADMIN""DEVELOPER"的用户才能访问这个方法,而我们的用户只有角色"USER"所以他们的请求此时被拒绝。

    @PreAuthorize 规则似乎是唯一被考虑的规则,但那是因为它更具体。
    如果HttpSecurity 中的规则更具体,则请求将在到达@PreAuthorize 之前在过滤器链中被拒绝。

    【讨论】:

      猜你喜欢
      • 2017-09-21
      • 2020-10-21
      • 1970-01-01
      • 2014-04-28
      • 2020-05-07
      • 2018-07-26
      • 1970-01-01
      • 2020-03-12
      • 1970-01-01
      相关资源
      最近更新 更多