我已经改变了用户在我的后端进行身份验证的方式。从现在开始,我将从Firebase接收JWT令牌,然后在我的Sping Boot 服务器上进行验证。
到目前为止,这工作得很好,但是有一个变化我不太满意,那就是principal-object现在是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令牌时,在我的数据库中创建一个用户记录,而该用户还不存在。
此外,我的许多业务逻辑目前依赖于作为用户实体业务对象的主体。我可以修改这些代码,但这是一项乏味的工作,谁不想回顾一下几行遗留代码呢?
4条答案
按热度按时间ncgqoxb01#
我做的和朱利安·艾奇卡德有点不同。
在我的
WebSecurityConfigurerAdapter
中,我设置了一个Customizer
如下:customAuthenticationProvider
是一个JwtResourceServerCustomizer
,我是这样实现的:我将
NimbusJwtDecoder
配置为:最后,我们需要一个自定义的
AuthenticationProvider
,它将返回我们想要的Authentication
对象:cs7cruho2#
到目前为止,这一切都很顺利,但有一个变化我不太满意,那就是主体对象现在是org.springframework.security.oauth2.jwt.Jwt,而不是像以前那样是AppUserEntity,即用户模型。
在我的应用程序中,我通过滚动我自己的
JwtAuthenticationFilter
而不是使用BearerTokenAuthenticationFilter
来避免这个问题,然后将我的User
实体设置为Authentication
对象中的principal
。但是,在我的例子中,这几乎是根据JWT声明构造一个User
,这可能是一个不好的做法:SonarLint提示使用DTO来降低某人使用已泄露的JWT令牌将任意数据注入到其用户记录中的风险。我不知道这是否是一个大问题-如果您不能信任您的JWT,则会有其他问题,恕我直言。我不知道这是否是最好的方法,但是我打算在发现一个用户的有效JWT令牌(该用户还不存在)后,在我的数据库中创建一个用户记录。
请记住,应用程序应该以无状态的方式验证JWT,只通过验证它们的签名。您不应该在每次验证它们时都访问数据库。因此,最好使用如下方法调用来创建用户记录
您需要将涉及此用户的更改持久化到数据库中。
s2j5cfk03#
自
不适用于
您可以创建一个自定义类来扩展HttpServletRequestWrapper
然后在过滤器中执行以下操作:
xvw2m8pv4#
根据Josh Cummings的回答在issue #7834 make中配置:
和实现工厂方法,例如:
请注意,控制器的方法应该注入
JwtUser jwtUser
,而不注入任何@AuthenticationPrincipal