我遇到了Spring Security + Spring Webflux + X509 Client证书验证的问题。请给我一些帮助吗?
使用以下最少的工作代码:
@RestController
@SpringBootApplication
public class X509AuthenticationServer {
public static void main(String[] args) {
SpringApplication.run(X509AuthenticationServer.class, args);
}
@RequestMapping(value = "/test")
public Mono<String> test() {
return Mono.just("\n test \n");
}
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity serverHttpSecurity, UserDetailsRepositoryReactiveAuthenticationManager authenticationManager, X509PrincipalExtractor principalExtractor) {
return serverHttpSecurity.authorizeExchange().anyExchange().authenticated().and().x509().principalExtractor(principalExtractor).authenticationManager(authenticationManager).and().build();
}
@Bean
public X509PrincipalExtractor principalExtractor() {
return new SubjectDnX509PrincipalExtractor();
}
@Bean
public UserDetailsRepositoryReactiveAuthenticationManager authenticationManager(ReactiveUserDetailsService reactiveUserDetailsService) {
return new UserDetailsRepositoryReactiveAuthenticationManager(reactiveUserDetailsService);
}
@Bean
public MapReactiveUserDetailsService mapReactiveUserDetailsService() {
return new MapReactiveUserDetailsService(User.withUsername("USER").authorities(new SimpleGrantedAuthority("USER")).password("").build());
}
}
server.ssl.key-store=/keystore.jks
server.ssl.key-store-password=123456
server.ssl.key-alias=localhost
server.ssl.key-password=123456
server.ssl.enabled=true
server.ssl.trust-store=/truststore.jks
server.ssl.trust-store-password=123456
server.ssl.client-auth=need
server.port=8443
spring.security.user.name=test
spring.security.user.password=test
logging.level.root=DEBUG
我期望这可以工作,即我可以进行X509证书验证。但是,我遇到了一个我不理解的异常奇怪的异常
2020-10-15 20:04:57.773 DEBUG [,9dfd3873894ac7fe,9dfd3873894ac7fe,true] 8646 --- [ctor-http-nio-3] .w.a.p.x.SubjectDnX509PrincipalExtractor : Subject DN is 'CN=(I see the correct CN), OU=zzzzzz, OU=xxxxxx, O=cccccc, C=US'
2020-10-15 20:04:57.773 DEBUG [,9dfd3873894ac7fe,9dfd3873894ac7fe,true] 8646 --- [ctor-http-nio-3] .w.a.p.x.SubjectDnX509PrincipalExtractor : Extracted Principal name is(I see the correct CN)
2020-10-15 20:04:57.785 DEBUG [,9dfd3873894ac7fe,9dfd3873894ac7fe,true] 8646 --- [ctor-http-nio-3] a.w.r.e.AbstractErrorWebExceptionHandler : [a8f68710/1-1] Resolved [ClassCastException: class sun.security.x509.X509CertImpl cannot be cast to class java.lang.String (sun.security.x509.X509CertImpl and java.lang.String are in module java.base of loader 'bootstrap')] for HTTP GET /test
2020-10-15 20:04:57.786 ERROR [,9dfd3873894ac7fe,9dfd3873894ac7fe,true] 8646 --- [ctor-http-nio-3] a.w.r.e.AbstractErrorWebExceptionHandler : [a8f68710/1-1] 500 Server Error for HTTP GET "/test
java.lang.ClassCastException: class sun.security.x509.X509CertImpl cannot be cast to class java.lang.String (sun.security.x509.X509CertImpl and java.lang.String are in module java.base of loader 'bootstrap')
at org.springframework.security.authentication.AbstractUserDetailsReactiveAuthenticationManager.authenticate(AbstractUserDetailsReactiveAuthenticationManager.java:99) ~[spring-security-core-5.3.4.RELEASE.jar:5.3.4.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
问题:“ sun.security.x509.X509CertImpl和java.lang.String在加载程序'bootstrap'的java.base模块中”是什么意思,我怎么会遇到这个问题,以及如何解决它?
谢谢
问题在于,AbstractUserDetailsReactiveAuthenticationManager
旨在验证用户名/密码而不是X509证书,因此它试图将X509凭据转换为字符串以像密码一样对其进行验证。
相反,请删除ReactiveAuthenticationManager
Bean,并允许ReactivePreAuthenticatedAuthenticationManager
使用从ReactiveUserDetailsService
Bean自动创建的默认值。的SubjectDnX509PrincipalExtractor
是默认的,所以没有必要明确规定,但如果你需要定制它只是暴露它作为一个Bean,它会默认使用。
@RestController
@SpringBootApplication
public class X509AuthenticationServer {
public static void main(String[] args) {
SpringApplication.run(X509AuthenticationServer.class, args);
}
@RequestMapping(value = "/test")
public Mono<String> test() {
return Mono.just("\n test \n");
}
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.x509();
// @formatter:on
return http.build();
}
@Bean
public MapReactiveUserDetailsService mapReactiveUserDetailsService() {
return new MapReactiveUserDetailsService(User.withUsername("USER").authorities("USER").password("").build());
}
}
您还可以在https://github.com/spring-projects/spring-security-samples/blob/592e4f89d2819f255340518a2c91b7e6eab6ed3e/reactive/webflux/java/authentication/x509/src/main/java/example/WebfluxX509Application中找到完整的示例。爪哇
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句