gst*_*low 9 java spring-security spring-boot minio spring-webflux
我有 spring-boot 应用程序,其中包含使用 Spring Web Flux 编写的其余服务。
现在我使用登录名/密码授权访问 minio,它工作正常。
现在我想用 STS minio 令牌交换应用程序 JWT 令牌,并且我实现了测试方法:
@PostMapping
public boolean test(JwtAuthenticationToken token) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
MinioClient minioClient =
MinioClient.builder()
.region(...)
.endpoint(...)
.credentialsProvider(new WebIdentityProvider(
() -> new Jwt(token.getToken().getTokenValue(), 1000),
String.valueOf(...),
null,
null,
null,
null,
null))
.build();
return minioClient.bucketExists("mybucket").build());
}
Run Code Online (Sandbox Code Playgroud)
此代码成功运行并返回,true因为mybucket实际存在。
但这只是测试,我需要进行minioClient配置。这里的问题是我必须在那里有凭证提供者。
所以我创建了以下配置:
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.region(...)
.endpoint(...)
.credentialsProvider(new WebIdentityProvider(
() -> {
String block = null;
try {
block = ReactiveSecurityContextHolder
.getContext()
.map(context -> {
return context
.getAuthentication()
.getPrincipal();
}
)
.cast(Jwt.class)
.map(Jwt::token)
.block();
} catch (Exception e) {
// it fails here <=======
System.out.println(e);
}
Jwt jwt = new Jwt(String.valueOf(block),
1000);
return jwt; },
String.valueOf(...),
null,
null,
null,
null,
null))
.build();
}
Run Code Online (Sandbox Code Playgroud)
但不幸的是方法block()失败并出现异常:
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-6
Run Code Online (Sandbox Code Playgroud)
有什么想法如何修复它吗?
PS_
我试过
.toFuture()
.get();
Run Code Online (Sandbox Code Playgroud)
代替 。block();
但它返回 null
正如Numichi在评论中所说,你必须留在反应堆环境中。一种选择是创建类型为 的 bean Mono<MinioClient>。
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Mono<MinioClient> reactiveMinio() {
return ReactiveSecurityContextHolder.getContext()
.map(securityContext ->
(Jwt)securityContext.getAuthentication().getPrincipal())
.map(jwt -> MinioClient.builder()
.region("someRegion")
.endpoint("someEndpoint")
.credentialsProvider(webIdentityProvider(jwt.token()))
.build());
}
private WebIdentityProvider webIdentityProvider(String token) {
return new WebIdentityProvider(() -> new Jwt(token, 1000),
"stsEndpoint",
null,
null,
null,
null,
null);
}
Run Code Online (Sandbox Code Playgroud)
我认为 bean 范围应该是原型,因为MinioClient它绑定到安全上下文。
这是反应式的示例用法MinioClient:
@RestController
public class MinioTest {
private Mono<MinioClient> minioClient;
public MinioTest(Mono<MinioClient> minioClient) {
this.minioClient = minioClient;
}
@GetMapping("/minio")
public Mono<Object> client() {
return minioClient
.map(minio -> {
try {
return minio.bucketExists(BucketExistsArgs
.builder()
.bucket("my-bucketname")
.build());
} catch (Exception e) {
return new Exception(e);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1258 次 |
| 最近记录: |