Oauth2;如何解决同时进行的多个异步 api 调用期间 AccessToken 过期的问题?
Oauth2; How to solve the issue with expired AccessToken during multiple async api calls , made concurrently?
我在我的应用程序中使用 Spring Security Oauth2 作为安全层。在并发异步调用出现之前,一切都运行良好。
谁能告诉我如何处理下一个案例:
1.客户端有一个已经过期的accessToken。
2. 客户端对我的 api 进行了两次并发异步 api 调用(例如:Thread1、Thread2)。
3. Thread1 在 Thread2 之前收到错误:"accessToken expired"。
4. 通过使用refreshToken Thread1 接收到一个新的accessToken = qqqqq。
5. 在 Thread1 使用新的 accessToken = qqqqq 对服务器进行新调用之前,Thread2 收到错误:"accessToken expired"。
6. 通过使用 refreshToken Thread2 接收新的 accessToken = wwwww 并删除 accessToken = qqqqq。
7. 在这里,Thread1 使用 accessToken = qqqqq 调用未激活的服务器。
8. 理论上,通过使彼此无效来循环两个线程是完全可能的。
我将不胜感激任何帮助,谢谢。
如果您已经控制了客户端,那么您可以将版本号附加到访问令牌 - 如果线程尝试使用旧版本号刷新访问令牌,那么当前(最近刷新的)访问令牌是而是返回。
public class AccessToken {
private int currentVersion;
private String accessToken;
private static AccessToken currentToken;
public static synchronized AccessToken refresh(AccessToken token) {
if(token.currentVersion == currentToken.currentVersion) {
AccessToken newToken = // refresh token
newToken.currentVersion = currentToken.currentVersion + 1;
currentToken = newToken;
}
return currentToken;
}
}
如果您对客户端没有任何控制权 and/or 更愿意修复此服务器端,那么几个选项是:
- 允许客户端每个线程使用一个访问令牌,而不是要求它们跨线程共享一个全局访问令牌。
- 禁止每隔 5 秒多次刷新访问令牌。这样即使客户端遇到刷新循环,他们仍然应该能够取得一些进展。
- 公开一个仅在提供正确的当前令牌时才刷新令牌的方法,以便客户端可以有条件地更新其访问令牌(您仍然需要公开当前方法以绝对刷新令牌,以防万一客户端忘记了旧的访问令牌)。
我在我的应用程序中使用 Spring Security Oauth2 作为安全层。在并发异步调用出现之前,一切都运行良好。
谁能告诉我如何处理下一个案例:
1.客户端有一个已经过期的accessToken。
2. 客户端对我的 api 进行了两次并发异步 api 调用(例如:Thread1、Thread2)。
3. Thread1 在 Thread2 之前收到错误:"accessToken expired"。
4. 通过使用refreshToken Thread1 接收到一个新的accessToken = qqqqq。
5. 在 Thread1 使用新的 accessToken = qqqqq 对服务器进行新调用之前,Thread2 收到错误:"accessToken expired"。
6. 通过使用 refreshToken Thread2 接收新的 accessToken = wwwww 并删除 accessToken = qqqqq。
7. 在这里,Thread1 使用 accessToken = qqqqq 调用未激活的服务器。
8. 理论上,通过使彼此无效来循环两个线程是完全可能的。
我将不胜感激任何帮助,谢谢。
如果您已经控制了客户端,那么您可以将版本号附加到访问令牌 - 如果线程尝试使用旧版本号刷新访问令牌,那么当前(最近刷新的)访问令牌是而是返回。
public class AccessToken {
private int currentVersion;
private String accessToken;
private static AccessToken currentToken;
public static synchronized AccessToken refresh(AccessToken token) {
if(token.currentVersion == currentToken.currentVersion) {
AccessToken newToken = // refresh token
newToken.currentVersion = currentToken.currentVersion + 1;
currentToken = newToken;
}
return currentToken;
}
}
如果您对客户端没有任何控制权 and/or 更愿意修复此服务器端,那么几个选项是:
- 允许客户端每个线程使用一个访问令牌,而不是要求它们跨线程共享一个全局访问令牌。
- 禁止每隔 5 秒多次刷新访问令牌。这样即使客户端遇到刷新循环,他们仍然应该能够取得一些进展。
- 公开一个仅在提供正确的当前令牌时才刷新令牌的方法,以便客户端可以有条件地更新其访问令牌(您仍然需要公开当前方法以绝对刷新令牌,以防万一客户端忘记了旧的访问令牌)。