使用keycloak(OAUTH)保护rest,如下所示:
@PreAuthorize("hasRole('user')")
@GetMapping(value = "/employees", produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<List<Employee>> findAll(java.security.Principal principal,
@RequestParam(name = "filterationCriteria", required = false) String fields) {
if(Objects.nonNull(principal)){
return employeeManagementService.findAll(fields);
}
return null;
}我想使用webclient来使用这个api,如下所示:
public <T> T get(URI url, Class<T> responseType, Principal principal) {
return WebClient.builder().build().get().uri(url)
.header("Authorization", "Basic " + principal)
.retrieve().bodyToMono(responseType).block();
}上述方法在findAll()方法的异常下面抛出,如果找不到主体,通常会发生这种情况:
org.springframework.web.reactive.function.client.WebClientResponseException$Unauthorized: 401
未经授权从GET
我是不是做错了什么,这是发送主体的正确方式吗?
如有任何建议,将不胜感激。
提前谢谢。
更新
我使用来自不同服务的webclient向安全的rest发送请求,并且需要手动传递主体(可能会将其包含到头中)。
如果我只是在下面这样做:WebClient.builder().build().get().uri(url).retrieve().bodyToMono(responseType).block(),那么主体在findAll方法中是空的。
安全配置
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.anyRequest().permitAll().and()
.csrf().disable();
}注意:我已经在方法级别上设置了授权约束。
发布于 2021-05-01 18:55:00
I have found a solution. the principal has to be sent like this:
public <T> T get(URI url, Class<T> responseType, Principal principal) {
RequestHeadersSpec uri = webClient.get().uri(url);
if (Objects.nonNull(principal)) {
uri = uri.header("Authorization", "Bearer "
+ ((KeycloakAuthenticationToken) principal).getAccount().getKeycloakSecurityContext().getTokenString());
}
ResponseSpec response = uri.retrieve();
Mono<T> bodyToMono = response.bodyToMono(responseType);
return bodyToMono.block();
}https://stackoverflow.com/questions/67346319
复制相似问题