Spring security 使用oidc的Spring安全性:刷新令牌

Spring security 使用oidc的Spring安全性:刷新令牌,spring-security,jwt,refresh-token,openid-connect,Spring Security,Jwt,Refresh Token,Openid Connect,带有Spring Security 5的Spring Boot 2可以配置为使用openID连接ID提供程序进行身份验证。 我仅通过配置Spring安全性就成功地建立了我的项目——这与各种完全预配置的安全机制(如会话固定的缓解)配合得很好 但Spring安全性似乎不会在令牌(存储在会话中)过期时自行刷新令牌 有这样的设置吗?还是我必须自己去关注刷新 更新:Spring Boot 2.1已经发布,因此是时候重新考虑这个问题了。我仍然不知道accessToken现在是否可以自动刷新,或者我是否必须为

带有Spring Security 5的Spring Boot 2可以配置为使用openID连接ID提供程序进行身份验证。 我仅通过配置Spring安全性就成功地建立了我的项目——这与各种完全预配置的安全机制(如会话固定的缓解)配合得很好

但Spring安全性似乎不会在令牌(存储在会话中)过期时自行刷新令牌

有这样的设置吗?还是我必须自己去关注刷新


更新:Spring Boot 2.1已经发布,因此是时候重新考虑这个问题了。我仍然不知道accessToken现在是否可以自动刷新,或者我是否必须为此编写代码……

即使是100个代表点数的奖励也没有给出答案。因此,我想目前还没有实现使用Spring Security自动刷新访问令牌的机制


一个有效的替代方案似乎是使用能够刷新令牌的spring boot Keyclope适配器。

根据文档

当使用正确配置的WebClient时(如文档中所示),它将自动刷新

Spring Security将自动刷新过期令牌(如果存在刷新令牌)

支持刷新令牌的功能矩阵也支持这一点

在SpringSecurity5上有一个较旧的博客,它允许您访问可以手动执行的bean

Authentication authentication =
    SecurityContextHolder
        .getContext()
        .getAuthentication();

OAuth2AuthenticationToken oauthToken =
    (OAuth2AuthenticationToken) authentication;
将有一个OAuth2AuthorizedClientService在Spring应用程序上下文中自动配置为bean,因此您只需要将它注入到您将使用它的任何地方

而且,现在找不到它,但我假设作为
OAuth2AuthorizedClientChangeFilterFunction
的一部分,有调用来执行刷新。

根据这一点,令牌似乎是有意不刷新的:

ID令牌通常带有到期日期。RP可能 依靠它使RP会话过期

春天不会。最后提到了两个增强功能,它们应该可以解决一些刷新问题——它们都还没有解决

作为一种解决方法,我实现了一个GenericFilterBean,它在当前安全上下文中检查令牌并清除身份验证。因此,需要一个新的令牌

@Configuration
public class RefreshTokenFilterConfig {

    @Bean
    GenericFilterBean refreshTokenFilter(OAuth2AuthorizedClientService clientService) {
        return new GenericFilterBean() {
            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (authentication != null && authentication instanceof OAuth2AuthenticationToken) {
                    OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
                    OAuth2AuthorizedClient client =
                            clientService.loadAuthorizedClient(
                                    token.getAuthorizedClientRegistrationId(),
                                    token.getName());
                    OAuth2AccessToken accessToken = client.getAccessToken();
                    if (accessToken.getExpiresAt().isBefore(Instant.now())) {
                        SecurityContextHolder.getContext().setAuthentication(null);
                    }
                }
                filterChain.doFilter(servletRequest, servletResponse);
            }
        };
    }
}
此外,我还必须将过滤器添加到安全配置中:

@Bean
public WebSecurityConfigurerAdapter webSecurityConfigurer(GenericFilterBean refreshTokenFilter) {
    return new WebSecurityConfigurerAdapter() {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                   .addFilterBefore(refreshTokenFilter,  AnonymousAuthenticationFilter.class)
通过版本2.2.7中的spring boot starter父项和依赖项实现。版本:

  • SpringBootStarterWeb
  • 弹簧启动安全
  • spring-boot-starter-oauth2-client

我很欣赏关于这种解决方法的意见,因为我仍然不确定Spring Boot是否真的需要这样的开销。

最新文档指出,如果提供了刷新令牌,Spring security应该自动尝试刷新它。也支持这一点supported@DarrenForsythethanx的链接-如何满足这一点作为一个答案,这样我就可以分配赏金给你?因此,似乎网络客户端处理刷新令牌。因此,据我所知,应用程序在端点上收到一个请求,只有当控制器试图通过webClient使用访问令牌时,才会使用刷新令牌。有趣的概念。。。KeyClope适配器已经用传入请求刷新accesstoken…我不确定webclient支持获取和刷新令牌等的底层实现,我自己目前遇到了一个问题,但是从我所看到的代码来看,如果您已经进行了身份验证,那么它将尝试刷新,如果刷新令牌在对给定提供者的请求上可用,则会对auth对象进行刷新。也有可能获得较低级别的bean并自己动手,有这样一个例子吗?你知道如何使用新的spring安全版本来完成吗???我们可以使用任何自定义过滤器来刷新令牌和更新主体吗?谢谢这个详细答案!对于仍在寻找解决方案的人来说,它就在这里。WebClient是一种补救方法。
@Bean
public WebSecurityConfigurerAdapter webSecurityConfigurer(GenericFilterBean refreshTokenFilter) {
    return new WebSecurityConfigurerAdapter() {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                   .addFilterBefore(refreshTokenFilter,  AnonymousAuthenticationFilter.class)