如何从 webfilter 中的 oauth2 令牌中提取 accountId
How to extract accountId from oauth2 token in webfilter
我在我的程序中使用 webflux 和 oauth2 安全性 (keycloack as UAA server
) 我想从 oauth2 jwt 中提取一些信息并且我做得很好。但我需要在过滤器中获取一些信息。
当我使用我的旧方法时,它在 filter (WebFilter
) 中不起作用。
有没有办法解析令牌并从中获取信息?
我的方法是正确的还是我应该使用 springSecurityFilterChain
而不是 WebFilter 来提取它?
我想检查令牌中的 accountId 和客户端使用过滤器发送的 url 中的 accountId。
听说是我提取 accountId 的代码,它在 WebFilter 中不起作用,但当我使用它时它可以工作服务或控制器
public class SecurityFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).map(Principal::getName).filter((accountId) -> accountId.equals(clientAccountId)
.switchIfEmpty(Mono.error(new SystemException("401 ERROR")));;
return webFilterChain.filter(serverWebExchange);
}
听说是我提取accountId的第二种方法:
public class SecurityFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
serverWebExchange.getPrincipal().map(Principal::getName).filter((accountId) -> accountId.equals(clientAccountId). .switchIfEmpty(Mono.error(new SystemException("401 ERROR")));;
return webFilterChain.filter(serverWebExchange);
}
我的安全配置是:
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.pathMatchers("/api/**").authenticated()
// .pathMatchers("/**").permitAll()
.anyExchange().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.BAD_REQUEST))
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(grantedAuthoritiesExtractor());
return http.build();
}
我想我应该有另一个 SecurityWebFilterChain
方法来为我做这个 ??
您正在寻找这样的东西
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
var clientAccountId = "clientId";
return exchange.getPrincipal()
.map(Principal::getName)
.flatMap((accountId) -> {
if (accountId.equals(clientAccountId) && exchange.getRequest().getPath().value().equals("/my/api")) {
return Mono.just(accountId);
}
return Mono.error(new IllegalArgumentException("401 ERROR"));
})
.flatMap(tokenJwt -> chain.filter(exchange))
.onErrorResume(r -> {
exchange.getResponse().setRawStatusCode(HttpStatus.UNAUTHORIZED.value());
return exchange.getResponse().setComplete();
});
}
注意:当你使用反应式时,直到你或spring订阅它,它才会被执行。
我在我的程序中使用 webflux 和 oauth2 安全性 (keycloack as UAA server
) 我想从 oauth2 jwt 中提取一些信息并且我做得很好。但我需要在过滤器中获取一些信息。
当我使用我的旧方法时,它在 filter (WebFilter
) 中不起作用。
有没有办法解析令牌并从中获取信息?
我的方法是正确的还是我应该使用 springSecurityFilterChain
而不是 WebFilter 来提取它?
我想检查令牌中的 accountId 和客户端使用过滤器发送的 url 中的 accountId。
听说是我提取 accountId 的代码,它在 WebFilter 中不起作用,但当我使用它时它可以工作服务或控制器
public class SecurityFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).map(Principal::getName).filter((accountId) -> accountId.equals(clientAccountId)
.switchIfEmpty(Mono.error(new SystemException("401 ERROR")));;
return webFilterChain.filter(serverWebExchange);
}
听说是我提取accountId的第二种方法:
public class SecurityFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
serverWebExchange.getPrincipal().map(Principal::getName).filter((accountId) -> accountId.equals(clientAccountId). .switchIfEmpty(Mono.error(new SystemException("401 ERROR")));;
return webFilterChain.filter(serverWebExchange);
}
我的安全配置是:
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.pathMatchers("/api/**").authenticated()
// .pathMatchers("/**").permitAll()
.anyExchange().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.BAD_REQUEST))
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(grantedAuthoritiesExtractor());
return http.build();
}
我想我应该有另一个 SecurityWebFilterChain
方法来为我做这个 ??
您正在寻找这样的东西
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
var clientAccountId = "clientId";
return exchange.getPrincipal()
.map(Principal::getName)
.flatMap((accountId) -> {
if (accountId.equals(clientAccountId) && exchange.getRequest().getPath().value().equals("/my/api")) {
return Mono.just(accountId);
}
return Mono.error(new IllegalArgumentException("401 ERROR"));
})
.flatMap(tokenJwt -> chain.filter(exchange))
.onErrorResume(r -> {
exchange.getResponse().setRawStatusCode(HttpStatus.UNAUTHORIZED.value());
return exchange.getResponse().setComplete();
});
}
注意:当你使用反应式时,直到你或spring订阅它,它才会被执行。