spring - 使用 x.509 身份验证时避免基本身份验证

标签 spring spring-boot kotlin spring-security

我已经创建了一个基于 Spring WebFlux 的 REST API,它通过 X.509 身份验证受到保护。我遵循了本指南 https://www.baeldung.com/x-509-authentication-in-spring-security创建所有证书。

路由器实现:

@Configuration
class LogRouter {

    @Bean
    fun functionalRoutes(handler: LogHandler): RouterFunction<ServerResponse> =
        route()
            .route(RequestPredicates.path("/")) {
                ServerResponse.ok().body(Mono.just("I am alive"))
            }
            .nest(RequestPredicates.path("/api").and(RequestPredicates.accept(MediaType.APPLICATION_JSON))) { builder ->
                builder.GET("/fn/mono", handler::monoMessage)
                    .POST("/fn/mono", handler::monoPostMessage)
            }
            .build()
}

和应用实现:

@SpringBootApplication
@EnableWebFluxSecurity
class RestplayApplication {

    @Bean
    fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain? {
        val principalExtractor = SubjectDnX509PrincipalExtractor()

        principalExtractor.setSubjectDnRegex("OU=(.*?)(?:,|$)")

        val authenticationManager = ReactiveAuthenticationManager { authentication: Authentication ->
            authentication.isAuthenticated = "Trusted Org Unit" == authentication.name
            Mono.just(authentication)
        }

        http
            .x509 { x509 ->
                x509
                    .principalExtractor(principalExtractor)
                    .authenticationManager(authenticationManager)
            }
            .authorizeExchange { exchanges ->
                exchanges
                    .anyExchange().authenticated()
            }
        return http.build()

    }
}

fun main(args: Array<String>) {
    runApplication<RestplayApplication>( *args)
}

我使用 Firefox 浏览器来测试 x.509 身份验证,并且我已将自签名证书(rootCA.crt) 添加到 Firefox:

enter image description here

包含客户端证书(clientBob.p12)。

enter image description here

在浏览器中调用链接时,它显示基本身份验证表单:

enter image description here

但是,我希望身份验证表单不会出现,因为我在浏览器中提供了有效的客户端证书。

为什么每次都出现基本形式?

代码托管在 https://github.com/softshipper/restplay 上.证书的密码始终是 changeit

最佳答案

我调试了它,问题似乎是您的客户端证书 clientBob.crt 不包含主题的组织单位字段,并且您的 principalExtractor 设置为提取该字段。结果,您的 principalExtractor 失败,因此它调用 authenticationFailureHandler,默认设置为提示基本身份验证。

可能的解决方案可能是:

  1. 使用包含主体组织单位的客户端证书,并将其设置为“受信任的组织单位”。

  2. 更改 principalExtractor 正则表达式,使其使用不同的字段。默认使用通用名称 (CN)。如果你确实编辑了它,那么记得同时更新你的 authenticationManager 以检查“Bob”而不是“Trusted Org Unit”

关于spring - 使用 x.509 身份验证时避免基本身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71483390/

相关文章:

java - 具有通用约束的 JSON Jackson

android - 为什么 SharedPreferences 需要两个键?

kotlin - 无法加载AndroidJUnit4的代表赛跑者 'androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner'

Spring AOP : Capture inner private method calls (@EnableAspectJAutoProxy)

tomcat - 我可以为 Spring Boot 的嵌入式 tomcat 启用 tomcat 管理器应用程序吗?

java - Mapper获取用@JsonIgnore注释的字段的空值(resttemplate)

spring - 如何从现有的 Spring REST API 生成 OpenAPI 3.0 YAML 文件?

android - classes.jar' 已经包含条目 'META-INF/module_name_debug.kotlin_module' ,无法覆盖

java - 使用 Lombok 记录器记录时有没有办法屏蔽类值?

java - 我需要使用 websockets 将 ESP8266 连接到本地 Java 服务器的帮助