- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经更改了用户在我的后端进行身份验证的方式。从现在开始,我将从 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/
我是一名优秀的程序员,十分优秀!