首页 > 解决方案 > 使用 WebSecurityConfigurerAdapter 在 Spring boot 2.x 中进行身份验证处理

问题描述

我正在使用具有以下依赖关系的 Spring Boot 2.0.5 以实现 5.0.8 的弹簧安全性

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
 </dependency>

为了测试目的,我从下面的其余控制器中抛出了一个异常。

@GetMapping("/greeting")
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
        throw new org.springframework.security.authentication.BadCredentialsException("yoyo");
}

这就是配置类的样子,

    @Configuration    
    @EnableWebSecurity
    public class BasicConfiguration extends WebSecurityConfigurerAdapter {
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/error");
    
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable().authorizeRequests().antMatchers("/error").permitAll();
        }
    }

我已经添加了 /error ,因为它说 Spring Boot 文档,

Spring Boot 2.0 并没有太大偏离 Spring Security 的默认设置,因此在 Spring Boot 1.5 中绕过 Spring Security 的一些端点现在默认是安全的。其中包括错误端点和静态资源的路径,例如 /css/ 、 /js/、 /images/ 、 /webjars/、 /**/favicon.ico 。如果你想打开这些,你需要明确地配置它。

在 Spring Boot 应用程序类中添加以下内容

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class })

当我到达休息终点时,我得到,

{
    "timestamp": "2021-01-17T03:52:50.069+0000",
    "status": 403,
    "error": "Forbidden",
    "message": "Access Denied",
    "path": "/greeting"
}

但我希望状态 401 带有 "message": "yoyo" 如下所示,

{
    "timestamp": 2021-01-17T03:52:50.069+0000,
    "status": 401,
    "error": "Unauthorized",
    "message": "yoyo",
    "path": "/greeting"
}

我需要做哪些改变才能获得响应

标签: javaspringspring-bootrestspring-security

解决方案


添加http.exceptionHandling().authenticationEntryPoint(..)到 getUnauthorized而不是Forbiddenforerror字段。

@Configuration
@EnableWebSecurity
public class BasicConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/error");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests().antMatchers("/error").permitAll();

        http.exceptionHandling().authenticationEntryPoint((request, response, ex) -> {
            // You can add more logic to return different error codes
            response.sendError(401, "Unauthorized");
        });
    }
}

定义一个返回ex.getMessage()而不是Access Deniedformessage字段的新类。

@Component
public class CustomErrorAttributes extends DefaultErrorAttributes {
    @Override
    protected String getMessage(WebRequest webRequest, Throwable error) {
        return error.getMessage();
    }
}

输出:

{
    "timestamp": "2021-01-20T15:06:33.122+00:00",
    "status": 401,
    "error": "Unauthorized",
    "message": "yoyo",
    "path": "/greeting"
}

推荐阅读