如何禁用特定端点的身份验证?

Posted

技术标签:

【中文标题】如何禁用特定端点的身份验证?【英文标题】:How can I disable authentication for a specific endpoint? 【发布时间】:2020-09-19 00:03:17 【问题描述】:

Many对similar questions的回答解释说permitAll()的意思是“允许所有经过身份验证的用户”,如果你想跳过身份验证,你需要这样做

@Override
public void configure(WebSecurity web) throws Exception 
    web.ignoring().antMatchers("/chores");

这对我不起作用。

特别是,这是我想通过的控制器测试。

@SpringBootTest
@AutoConfigureMockMvc
public class ChoreApplicationTest

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void choresShouldBeEmptyAtStart() throws Exception
    
        this.mockMvc.perform(get("/chores")).
                andExpect(status().isOk());
    

测试结果:

java.lang.AssertionError: Status expected:<200> but was:<401>
Expected :200
Actual   :401

这是我设置安全性的方式:

@Configuration
@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter

    @Override
    public void configure(WebSecurity web) throws Exception
    
        web.ignoring().antMatchers("/chores");
        super.configure(web);
    

我认为您可以想象 Chores 控制器中的内容,但为了完整起见,以下是相关部分:

@RestController
public class ChoreController

    private final ChoreRepository repository;

    ChoreController(ChoreRepository repository)
    
        this.repository = repository;
    

    @GetMapping("/chores")
    List<Chore> all()
    
        return this.repository.findAll();
    

这是测试在输出中打印的请求:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /chores
       Parameters = 
          Headers = []
             Body = null
    Session Attrs = SPRING_SECURITY_SAVED_REQUEST=DefaultSavedRequest[http://localhost/chores]

那么为什么我的测试得到了 401 的返回码,我该如何解决呢?

【问题讨论】:

configure(WebSecurity web) 中删除 super.configure(web); 并确保在此方法中包含正确的端点。你能分享整个请求吗 @PatelRomil 如果没有super,我也会得到同样的结果。我已经编辑了整个请求。 您好@jon,您的SecurityConfigurer 类是否包含configure(HttpSecurity http) 方法?还要在SecurityConfigurer 中添加@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) 并告诉我 如果SecurityConfigurerconfigure(WebSecurity web)configure(HttpSecurity http) 两种方法组成。确保configure(WebSecurity web) 位于configure(HttpSecurity http) 上方 @PatelRomil 我在上面粘贴的SecurityConfigurer 正是我在代码中使用的。我添加了@EnableGlobalMethodSecurity 注释并得到了相同的结果。 【参考方案1】:

安全配置在 configure(WebSecurity web) 中是正确的,但问题是 SecurityConfigurer 由于包不同而没有被调用。

Spring Boot 从主应用程序 ChoreApplication 开始执行,还要注意所有类都在包 chore 中,而不是 SecurityConfigurer(在包安全中)

我们的主要应用程序类由@SpringBootApplication 组成,其中

@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan

@ComponentScan

默认情况下,spring 会处理 package chore 中的所有类,这里的问题是 spring 不知道其他包中的类的任何信息。 包安全

中的SecurityConfigurer

要调用SecurityConfigurer,我们必须将安全包添加为@ComponentScan(basePackages = "chores", "security")


ChoreApplication.java

package chores;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = "chores", "security")
public class ChoreApplication

    public static void main(String args[])
    
        SpringApplication.run(ChoreApplication.class, args);
    

SecurityConfigurer.java

package security;

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfigurer extends WebSecurityConfigurerAdapter 
    @Override
    public void configure(WebSecurity web) 
        web.ignoring().antMatchers("/chores");
    

你可能喜欢探索

Spring Security Configuration: HttpSecurity-vs-Webecurity

How to scan multiple paths using the @ComponentScan annotation

【讨论】:

【参考方案2】:
@ActiveProfiles("integration-test")
@SpringBootTest
@AutoConfigureMockMvc
public class ChoreApplicationTest


@Configuration
@EnableWebSecurity
@Profile("!integration-test")
public class SecurityConfigurer extends WebSecurityConfigurerAdapter

您可以通过这种方式忽略安全性。

如果您正在编写集成测试,那么您可以设置配置文件以忽略 spring 的某些特定区域。示例:安全性。

ActiveProfile 可以在配置文件中。

【讨论】:

以上是关于如何禁用特定端点的身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

如何绕过特定域的经过身份验证的端点上的弹簧安全性?

Spring boot:如何跳过特定端点的基本身份验证

如何从 Wordfence 禁用身份验证电子邮件发送?

DotNet Core Api - 特定端点的不同身份验证

Spring Security with Spring Boot:使用过滤器时允许未经身份验证的用户访问特定端点

在 spring-boot 中禁用特定 url 的 Keycloak 身份验证