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权限管理系统 欢迎关注

  • 相关阅读:
    Building Java Projects with Gradle
    Vert.x简介
    Spring及Spring Boot 国内快速开发框架
    dip vs di vs ioc
    Tools (StExBar vs Cmder)which can switch to command line window on context menu in windows OS
    SSO的定义、原理、组件及应用
    ModSecurity is an open source, cross-platform web application firewall (WAF) module.
    TDD中测试替身学习总结
    Spring事务银行转账示例
    台式机(华硕主板)前面板音频接口(耳机和麦克风)均无声的解决办法
  • 原文地址:https://www.cnblogs.com/leng-leng/p/13064890.html
Copyright © 2011-2022 走看看