gpt4 book ai didi

java - 将 Spring Security AbstractAuthenticationProcessingFilter 迁移到 WebFlux

转载 作者:行者123 更新时间:2023-12-02 09:12:14 24 4
gpt4 key购买 nike

我正在更新一个旧应用程序以使用 WebFlux,但在使用 Spring Security 处理 JWT 验证时我有点迷失了。

现有代码(适用于标准 Spring Web)如下所示:

(验证 Firebase token )

public class FirebaseAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {

private static final String TOKEN_HEADER = "X-Firebase-Auth";

public FirebaseAuthenticationTokenFilter() {
super("/v1/**");
}

@Override
public Authentication attemptAuthentication(
final HttpServletRequest request, final HttpServletResponse response) {

for (final Enumeration<?> e = request.getHeaderNames(); e.hasMoreElements(); ) {
final String nextHeaderName = (String) e.nextElement();
final String headerValue = request.getHeader(nextHeaderName);
}

final String authToken = request.getHeader(TOKEN_HEADER);
if (Strings.isNullOrEmpty(authToken)) {
throw new RuntimeException("Invaild auth token");
}

return getAuthenticationManager().authenticate(new FirebaseAuthenticationToken(authToken));
}

但是,当切换到 WebFlux 时,我们会丢失 HttpServletRequestHttpServletResponse。有一个 GitHub 问题表明有替代方法/修复 https://github.com/spring-projects/spring-security/issues/5328然而,随着它的完成,我无法确定实际更改了什么以使这项工作正常进行。

Spring Security 文档虽然很棒,但并没有真正解释如何处理用例。

关于如何进行的任何提示?

最佳答案

最终到达:

首先需要像以前一样使用自定义过滤器更新过滤器链

@Configuration
public class SecurityConfig {

private final FirebaseAuth firebaseAuth;

public SecurityConfig(final FirebaseAuth firebaseAuth) {

this.firebaseAuth = firebaseAuth;
}

@Bean
public SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http) {

http.authorizeExchange()
.and()
.authorizeExchange()
.pathMatchers("/v1/**")
.authenticated()
.and()
.addFilterAt(firebaseAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.csrf()
.disable();

return http.build();
}

private AuthenticationWebFilter firebaseAuthenticationFilter() {
final AuthenticationWebFilter webFilter =
new AuthenticationWebFilter(new BearerTokenReactiveAuthenticationManager());

webFilter.setServerAuthenticationConverter(new FirebaseAuthenticationConverter(firebaseAuth));
webFilter.setRequiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers("/v1/**"));

return webFilter;
}
}

该流程的主要工作是 FirebaseAuthenticationConverter,我在其中针对 Firebase 验证传入的 JWT,并针对它执行一些标准逻辑。

@Slf4j
@Component
@RequiredArgsConstructor
public class FirebaseAuthenticationConverter implements ServerAuthenticationConverter {

private static final String BEARER = "Bearer ";

private static final Predicate<String> matchBearerLength =
authValue -> authValue.length() > BEARER.length();

private static final Function<String, Mono<String>> isolateBearerValue =
authValue -> Mono.justOrEmpty(authValue.substring(BEARER.length()));

private final FirebaseAuth firebaseAuth;

private Mono<FirebaseToken> verifyToken(final String unverifiedToken) {
try {
final ApiFuture<FirebaseToken> task = firebaseAuth.verifyIdTokenAsync(unverifiedToken);

return Mono.justOrEmpty(task.get());
} catch (final Exception e) {
throw new SessionAuthenticationException(e.getMessage());
}
}

private Mono<FirebaseUserDetails> buildUserDetails(final FirebaseToken firebaseToken) {
return Mono.just(
FirebaseUserDetails.builder()
.email(firebaseToken.getEmail())
.picture(firebaseToken.getPicture())
.userId(firebaseToken.getUid())
.username(firebaseToken.getName())
.build());
}

private Mono<Authentication> create(final FirebaseUserDetails userDetails) {
return Mono.justOrEmpty(
new UsernamePasswordAuthenticationToken(
userDetails.getEmail(), null, userDetails.getAuthorities()));
}

@Override
public Mono<Authentication> convert(final ServerWebExchange exchange) {
return Mono.justOrEmpty(exchange)
.flatMap(AuthorizationHeaderPayload::extract)
.filter(matchBearerLength)
.flatMap(isolateBearerValue)
.flatMap(this::verifyToken)
.flatMap(this::buildUserDetails)
.flatMap(this::create);
}
}

关于java - 将 Spring Security AbstractAuthenticationProcessingFilter 迁移到 WebFlux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59311395/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com