无法通过 curl 通过基本身份验证

Can't pass basic authethication via curl

我尝试将基本身份验证添加到我的 Spring 启动非 Web 应用程序。 使用@WithMockUser 注释测试工作正常,但我无法使用正确的(看起来)凭据获得正确的 cURL。 我的安全配置:

@EnableWebFluxSecurity
public class SecurityConfig {
    @Value("${application.user}")
    private String user;
    @Value("${application.password}")
    private String password;

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(
            ServerHttpSecurity http) {
        return http.csrf().disable().authorizeExchange()
                .pathMatchers("/endpoint/v1/**").authenticated()
                .and().build();
    }

    @Bean
    public MapReactiveUserDetailsService userDetailsService() {
        UserDetails details = User
                .withUsername(user)
                .password(password)
                .roles("USER")
                .build();
        return new MapReactiveUserDetailsService(details);
    }

}

第一次尝试是使用 BCryptPasswordEncoder(但没有用),但为了简化问题我去掉了它。

我这样使用 curl:

curl -I --user user1:pass localhost:9094/endpoint/v1/health

与我 运行 我的应用程序具有相同的参数,但仍然得到:

HTTP/1.1 401 Unauthorized
transfer-encoding: chunked
WWW-Authenticate: Basic realm="Realm"
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
Referrer-Policy: no-referrer

控制器:

@RestController
@RequestMapping("/endpoint/v1")
@Slf4j
public class ApplicationController {

    @GetMapping("/health")
    @Timed
    public Mono<String> health() {
        log.info("Health ok");
        return Mono.just(String.format(STATUS, "ok"));
    }
}

我尝试邮递员,但结果相同。

谁能告诉我我做错了什么?

@Update

当我尝试使用正确的凭据登录时,来自终端的调试日志:

{"@timestamp":"2021-05-07T09:53:33.488+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] New http connection, requesting read","logger_name":"reactor.netty.http.server.HttpServerOperations","thread_name":"reactor-http-epoll-3","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.488+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] Initialized pipeline DefaultChannelPipeline{(BootstrapHandlers$BootstrapInitializerHandler#0 = reactor.netty.channel.BootstrapHandlers$BootstrapInitializerHandler), (reactor.left.httpCodec = io.netty.handler.codec.http.HttpServerCodec), (reactor.left.httpTrafficHandler = reactor.netty.http.server.HttpTrafficHandler), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}","logger_name":"reactor.netty.channel.BootstrapHandlers","thread_name":"reactor-http-epoll-3","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.498+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] Increasing pending responses, now 1","logger_name":"reactor.netty.http.server.HttpServerOperations","thread_name":"reactor-http-epoll-3","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.498+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] Handler is being applied: org.springframework.http.server.reactive.ReactorHttpHandlerAdapter@7f908d6a","logger_name":"reactor.netty.http.server.HttpServer","thread_name":"reactor-http-epoll-3","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.499+02:00","@version":"1","message":"[c6f8daa9-2] HTTP HEAD \"/endpoint/v1/health\"","logger_name":"org.springframework.web.server.adapter.HttpWebHandlerAdapter","thread_name":"reactor-http-epoll-3","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.500+02:00","@version":"1","message":"Created new WebSession.","logger_name":"org.springframework.web.server.session.DefaultWebSessionManager","thread_name":"boundedElastic-1","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.511+02:00","@version":"1","message":"[c6f8daa9-2] Completed 401 UNAUTHORIZED","logger_name":"org.springframework.web.server.adapter.HttpWebHandlerAdapter","thread_name":"boundedElastic-1","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.512+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] Last HTTP response frame","logger_name":"reactor.netty.http.server.HttpServerOperations","thread_name":"boundedElastic-1","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.512+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] No sendHeaders() called before complete, sending zero-length header","logger_name":"reactor.netty.http.server.HttpServerOperations","thread_name":"boundedElastic-1","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.514+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] Decreasing pending responses, now 0","logger_name":"reactor.netty.http.server.HttpServerOperations","thread_name":"reactor-http-epoll-3","level":"DEBUG","level_value":10000,"application":"myApp"}
{"@timestamp":"2021-05-07T09:53:33.514+02:00","@version":"1","message":"[id: 0xc6f8daa9, L:/127.0.0.1:9094 - R:/127.0.0.1:49572] Last HTTP packet was sent, terminating the channel","logger_name":"reactor.netty.http.server.HttpServerOperations","thread_name":"reactor-http-epoll-3","level":"DEBUG","level_value":10000,"application":"myApp"}

当您向应用程序添加 spring 安全性时,您会自动获得默认安全设置,here 在 spring 安全文档中对此进行了描述。

但是一旦您声明了自定义安全配置,您基本上就只能靠自己了。

以上配置中缺少的是显式配置您需要 http basic 身份验证。

这是通过添加完成的:

.httpBasic(withDefaults())

您可以阅读基本身份验证 here