gpt4 book ai didi

spring - 如何在 JWT 身份验证期间或之后设置自定义主体对象?

转载 作者:行者123 更新时间:2023-12-05 05:46:27 24 4
gpt4 key购买 nike

我已经更改了用户在我的后端进行身份验证的方式。从现在开始,我将从 Firebase 接收 JWT token ,然后在我的 Spring Boot 服务器上对其进行验证。

到目前为止一切正常,但有一个变化我不太满意,主体对象现在是 org.springframework.security.oauth2.jwt.Jwt 而不是一个 AppUserEntity,用户模型,和以前一样。

// Note: "authentication" is a JwtAuthenticationToken

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Jwt jwt = (Jwt) authentication.getPrincipal();

因此,经过一些阅读和调试后,我发现 BearerTokenAuthenticationFilter 基本上设置了 Authentication 对象,如下所示:

// BearerTokenAuthenticationFilter.java

AuthenticationManager authenticationManager = this.authenticationManagerResolver.resolve(request);

// Note: authenticationResult is our JwtAuthenticationToken
Authentication authenticationResult = authenticationManager.authenticate(authenticationRequest);

SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authenticationResult);
SecurityContextHolder.setContext(context);

正如我们所见,另一方面,它来自 authenticationManager,它是一个 org.springframework.security.authentication.ProviderManager 等等。兔子洞越来越深。

我没有找到任何可以让我以某种方式替换 Authentication 的东西。

那么计划是什么?

由于 Firebase 现在负责用户身份验证,因此可以在我的后端不知道的情况下创建用户。我不知道这是否是最好的方法,但我打算在发现尚不存在的用户的有效 JWT token 后,在我的数据库中简单地创建一个用户记录。

此外,我的很多业务逻辑目前都依赖于作为用户实体业务对象的委托(delegate)人。我可以更改此代码,但这是一项乏味的工作,谁不想回顾几行遗留代码?

最佳答案

我做的和 Julian Echkard 有点不同。

在我的 WebSecurityConfigurerAdapter 中,我设置了一个 Customizer,如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.oauth2ResourceServer()
.jwt(new JwtResourceServerCustomizer(this.customAuthenticationProvider));
}

customAuthenticationProvider 是一个 JwtResourceServerCustomizer,我是这样实现的:

public class JwtResourceServerCustomizer implements Customizer<OAuth2ResourceServerConfigurer<HttpSecurity>.JwtConfigurer> {

private final JwtAuthenticationProvider customAuthenticationProvider;

public JwtResourceServerCustomizer(JwtAuthenticationProvider customAuthenticationProvider) {
this.customAuthenticationProvider = customAuthenticationProvider;
}

@Override
public void customize(OAuth2ResourceServerConfigurer<HttpSecurity>.JwtConfigurer jwtConfigurer) {
String key = UUID.randomUUID().toString();
AnonymousAuthenticationProvider anonymousAuthenticationProvider = new AnonymousAuthenticationProvider(key);
ProviderManager providerManager = new ProviderManager(this.customAuthenticationProvider, anonymousAuthenticationProvider);
jwtConfigurer.authenticationManager(providerManager);
}
}

我正在像这样配置 NimbusJwtDecoder:

@Component
public class JwtConfig {

@Bean
public JwtDecoder jwtDecoder() {
String jwkUri = "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com";
return NimbusJwtDecoder.withJwkSetUri(jwkUri)
.build();
}

}

最后,我们需要一个自定义的 AuthenticationProvider,它将返回我们想要的 Authentication 对象:

@Component
public class JwtAuthenticationProvider implements AuthenticationProvider {

private final JwtDecoder jwtDecoder;

@Autowired
public JwtAuthenticationProvider(JwtDecoder jwtDecoder) {
this.jwtDecoder = jwtDecoder;
}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
BearerTokenAuthenticationToken token = (BearerTokenAuthenticationToken) authentication;

Jwt jwt;
try {
jwt = this.jwtDecoder.decode(token.getToken());
} catch (JwtValidationException ex) {
return null;
}

List<GrantedAuthority> authorities = new ArrayList<>();

if (jwt.hasClaim("roles")) {
List<String> rolesClaim = jwt.getClaim("roles");
List<RoleEntity.RoleType> collect = rolesClaim
.stream()
.map(RoleEntity.RoleType::valueOf)
.collect(Collectors.toList());

for (RoleEntity.RoleType role : collect) {
authorities.add(new SimpleGrantedAuthority(role.toString()));
}
}

return new JwtAuthenticationToken(jwt, authorities);
}

@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(BearerTokenAuthenticationToken.class);
}

}

关于spring - 如何在 JWT 身份验证期间或之后设置自定义主体对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71186138/

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