我们正在使用 spring security OAuth2 保护 REST 服务。应用程序可以调用 /oauth/authorize , /oauth/token/rest-api端点。 token 和 rest-api 端点是无状态的,不需要 session 。

我们可以在用户通过身份验证后使 session 无效吗?如果是这样,最好的方法是什么。我们希望用户在调用 /oauth/authorize 时始终登录制作。目前,调用/oauth/authorize只要 session 存在,就会跳过身份验证。

请您参考如下方法:

理解这个问题有点老了,我希望以下内容对那些寻找问题正确答案的人有所帮助

OP 询问的不是 token 失效,而是如何在用户身份验证成功通过并且有效的 access_token 或 authentication_code(用于随后获取 access_token)返回客户端后立即使 Spring OAuth2 服务器上的 httpSession 失效。

这个用例仍然没有开箱即用的解决方案。但是可以找到 spring-security-oauth 最活跃的贡献者 Dave Syer 的工作解决方法 here on GitHub

只需从那里复制代码:

@Service 
@Aspect 
public class SessionInvalidationOauth2GrantAspect { 
 
    private static final String FORWARD_OAUTH_CONFIRM_ACCESS = "forward:/oauth/confirm_access"; 
    private static final Logger logger = Logger.getLogger(SessionInvalidationOauth2GrantAspect.class); 
 
    @AfterReturning(value = "within(org.springframework.security.oauth2.provider.endpoint..*) && @annotation(org.springframework.web.bind.annotation.RequestMapping)", returning = "result") 
    public void authorizationAdvice(JoinPoint joinpoint, ModelAndView result) throws Throwable { 
 
        // If we're not going to the confirm_access page, it means approval has been skipped due to existing access 
        // token or something else and they'll be being sent back to app. Time to end session. 
        if (!FORWARD_OAUTH_CONFIRM_ACCESS.equals(result.getViewName())) { 
            invalidateSession(); 
        } 
    } 
 
    @AfterReturning(value = "within(org.springframework.security.oauth2.provider.endpoint..*) && @annotation(org.springframework.web.bind.annotation.RequestMapping)", returning = "result") 
    public void authorizationAdvice(JoinPoint joinpoint, View result) throws Throwable { 
        // Anything returning a view and not a ModelView is going to be redirecting outside of the app (I think).  
        // This happens after the authorize approve / deny page with the POST to /oauth/authorize. This is the time 
        // to kill the session since they'll be being sent back to the requesting app. 
        invalidateSession(); 
    } 
 
    @AfterThrowing(value = "within(org.springframework.security.oauth2.provider.endpoint..*) &&  @annotation(org.springframework.web.bind.annotation.RequestMapping)", throwing = "error") 
    public void authorizationErrorAdvice(JoinPoint joinpoint) throws Throwable { 
        invalidateSession(); 
    } 
 
    private void invalidateSession() { 
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) 
                .getRequest(); 
        HttpSession session = request.getSession(false); 
        if (session != null) { 
            logger.warn(String.format("As part of OAuth application grant processing, invalidating session for request %s", request.getRequestURI())); 
 
            session.invalidate(); 
            SecurityContextHolder.clearContext(); 
        } 
    } 
 
} 

添加 pom.xml
<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-aspects</artifactId> 
</dependency> 

另一种解决方案可能是将 session 超时设置为一些非常小的值。实现这一点的最简单方法是将以下内容放入 application.yml 配置:
server: 
  session: 
    timeout: 1 

但这不是理想的解决方案,因为提供者的最小值可能是 1(为无限 session 保留零)并且它以分钟而不是秒为单位


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!