问题背景
源码剖析
我们来看下 oauth2 的令牌方法机制,如果客户端 配置的 validitySeconds (令牌有效期) 大于 0 会返回当前令牌的有效时间 expires_in 参数,
1 2 3 4 5 6 7 8 9 10 11
| 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 参数
1 2 3 4 5 6 7 8
| 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 协议规范
1 2 3 4 5 6 7 8 9 10 11 12
| 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 的处理并不符合协议规范 。