zoukankan      html  css  js  c++  java
  • 聊聊 OAuth 2.0 的 token expire_in 使用

    问题背景

    有同学私信问了这样的问题,访问 pig4cloud 的演示环境 查看登录请求 network 返回报文如下:

    {
        "access_token":"16d35799-9cbb-4c23-966d-ab606029a623",
        "token_type":"bearer",
        "refresh_token":"495dbde5-1bbb-43c9-b06b-ecac50aa5d53",
        "expires_in":41000,
        "scope":"server"
    }
    

    而本地部署运行的时,登录请求返回的报文如下:

    {
        "access_token":"c262afbe-441e-4023-afb4-f88c8a0a7d51",
        "token_type":"bearer",
        "refresh_token":"ea642d50-5cf5-48ad-9ef9-cb57c9dde00a",
        "scope":"server"
    }
    

    缺少 expires_in 过期参数,所以客户端无法知悉何时执行刷新行为。

    源码剖析

    我们来看下 oauth2 的令牌方法机制,如果客户端 配置的 validitySeconds (令牌有效期) 大于 0 会返回当前令牌的有效时间 expires_in 参数,

    OAuth2AccessToken createAccessToken() {
      DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());
      int validitySeconds = getAccessTokenValiditySeconds(authentication.getOAuth2Request());
      if (validitySeconds > 0) {
        token.setExpiration(new Date(System.currentTimeMillis() + (validitySeconds * 1000L)));
      }
      token.setRefreshToken(refreshToken);
      token.setScope(authentication.getOAuth2Request().getScope());
    
      return accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token;
    }
    
    • tokenStore 去存储 令牌的时候,若过期参数为 0 或者 小于 0 Expiration 为空,不会设置有效时间也就意味着为永久有效,所以此时不会客户端响应 expires_in 参数
    if (token.getExpiration() != null) {
      int seconds = token.getExpiresIn();
      conn.expire(accessKey, seconds);
      conn.expire(authKey, seconds);
      conn.expire(authToAccessKey, seconds);
      conn.expire(clientId, seconds);
      conn.expire(approvalKey, seconds);
    }
    

    永久有效的令牌是否应该返回 expires_in 参数呢?

    我们先来看下oauth2 协议规范

    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-store
    Pragma: no-cache
    
    {
      "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
      "token_type":"bearer",
      "expires_in":3600,
      "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
      "scope":"create"
    }
    
    • access_token (必需) 授权服务器发出的访问令牌
    • token_type (必需)这是令牌的类型,通常只是字符串“bearer”。
    • expires_in (推荐)如果访问令牌过期过期时间。
    • refresh_token(可选)刷新令牌,在访问令牌过期后,可使用此令牌刷新。
    • scope(可选)如果用户授予的范围与应用程序请求的范围相同,则此参数为可选。

    此处 expires_in 推荐返回,无论是有设置有效期限制还是无有效期限制。所以此处 spring security oauth2 的处理并不符合协议规范 emmm 。

    项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注

  • 相关阅读:
    default关键字用法
    【转载】SpringMvc和servlet简单对比介绍
    build模式入门,build模式理解(转载)
    tomcat logs 目录下各日志文件的含义
    @Component, @Repository, @Service,@Controller的区别
    在项目开发时为什么要先写接口,再写实现类?
    java 中static关键字注意事项
    this关键字使用注意事项
    两个对象之前如何建立联系
    html页面监听事件
  • 原文地址:https://www.cnblogs.com/leng-leng/p/13064890.html
Copyright © 2011-2022 走看看