p.s*_*eef 5 spring-security spring-boot spring-security-oauth2
我正在使用 Spring security 和 spring oauth 在我的 Web 应用程序中进行身份验证(使用 jwt 令牌)。这工作正常,令牌被交换,我可以正确登录。但是,一旦登录,即使令牌过期,身份验证也不会过期。当我尝试重用令牌以从我的资源服务器获取资源时,它返回访问被拒绝,因为令牌不再有效。
我的网络应用程序是一个有状态(vaadin)网络应用程序。它使用会话来处理很多东西,我无法绕过它。使用 OAuth 进行身份验证后,它将使用“以前身份验证:org.springframework.security.oauth2.provider.OAuth2Authentication”来检查它是否已通过身份验证,我似乎这只会是“真”,直到会话被销毁。
我的 rest api 是状态/无会话的,因此每次都会正确验证令牌。如果过期,它将给出 401。
我发现处理这个问题的唯一方法是相当丑陋:如果 api 返回 401,则使会话无效。但是我想看到的是,Web 应用程序还会检查每个请求上令牌的有效性。使用会话时有没有办法做到这一点?
这是我的 webapp 的 oauth 安全配置部分。
@Configuration
@EnableOAuth2Sso
public class OAuthConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login**").permitAll()
.anyRequest().authenticated()
.and()
.logout()
.logoutSuccessUrl("/")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.and()
.exceptionHandling().authenticationEntryPoint((request, response, authException) -> response.sendRedirect("/login"));
}
}
Run Code Online (Sandbox Code Playgroud)
我花了一天时间研究这个问题以及 Spring 中 OAuth2 的机制。我可以确认上面的访问令牌过期后不会刷新的结果是正确的。对象 Authentication 在令牌过期之前或之后永远不会更改。但我找到了一种复杂的方法来刷新令牌而不发送 401。我使用了本教程中的一些代码
就是这样。首先创建一个自定义过滤器:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
OAuth2ClientContext ctxt = restTemplate.getOAuth2ClientContext();
if (ctxt != null) {
OAuth2AccessToken accessToken = ctxt.getAccessToken();
if (accessToken != null && accessToken.isExpired()) {
SecurityContextHolder.getContext().setAuthentication(null);
}
}
chain.doFilter(request, response);
}
Run Code Online (Sandbox Code Playgroud)
如果令牌已过期,此过滤器会将 Authentication 对象设置为 null。该过滤器必须在 AnonymousAuthenticationFilter 之前注册:
http.addFilterBefore(customFilter, AnonymousAuthenticationFilter.class);
Run Code Online (Sandbox Code Playgroud)
AnonymousAuthenticationFilter 将使用“匿名”属性填充身份验证。然后最后一个过滤器将抛出 AccessDeniedException 并开始从服务器获取令牌的过程。仅当 Authentication 对象填充了“匿名”属性时,AccessDeniedException 才能开始获取新令牌的过程。服务器实际上刷新令牌并发送回具有新过期时间的新令牌。
但问题仍然是,该财产是否曾打算以这种方式使用。也许这个过期时间是从令牌发出到客户端收到令牌之前的时间?如果令牌在过期后到达,则会引发异常。也许这就是它应该如何工作?
归档时间: |
|
查看次数: |
5222 次 |
最近记录: |