【发布时间】:2017-03-29 14:29:16
【问题描述】:
我正在开发一个 Android 应用程序,它使用 Oauth2 令牌来获得授权以访问安全资源。我使用第三方平台作为身份验证服务器(使用 OpenId Connect)。基本上我的问题是我想处理过期的刷新令牌。
当前情景
我有一个NetUtils 类,它的作用类似于单例,并使用安全的休息模板管理我的所有请求。该 rest 模板使用请求包装器为每个请求注入所需的 Authorization 标头。 NetUtils 类处理令牌和超时,将它们保存在用户首选项中并在需要时刷新它们。
但是,当刷新令牌本身过期时,问题就出现了。当我使用授权代码流时,我需要打开一个 WebView 并将用户重定向到登录页面,但是当 NetUtils 类确定刷新令牌已过期时,我注意到它。理想情况下,应用程序会启动一个 WebView,用户将再次登录并执行存储的请求。这是我刷新访问令牌的代码:
private AccessToken refreshToken(String idClient, String clientSecret, AccessToken accessToken) {
MultiValueMap<String, String> clientAuthenticationForm = new LinkedMultiValueMap<>();
clientAuthenticationForm.add("grant_type", "refresh_token");
clientAuthenticationForm.add("refresh_token", accessToken.getRefreshToken());
clientAuthenticationForm.add("client_id", idClient);
clientAuthenticationForm.add("client_secret", clientSecret);
try {
long lastClientRefresh = mPrefs.getLong(Preferences.LAST_LOGIN_TIME, Long.MIN_VALUE);
boolean refreshTokenExpired = lastClientRefresh
+ TimeUnit.SECONDS.toMillis(accessToken.getRefreshExpiresIn()) < System
.currentTimeMillis();
if (!refreshTokenExpired) {
return regularRestTemplate
.postForEntity(tokenUrl(), clientAuthenticationForm, AccessToken.class)
.getBody();
}else{
//How to cope with this?
return null;
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage(), ex);
throw ex;
}
}
其他选择
例如,其他选择是使刷新令牌长期存在并在每次应用启动时刷新它。我不得不提一下,client_id 和 client_secret 目前正在应用程序中进行硬编码(尽管客户端凭据授予并不意味着在生产中启用,因此仍然需要提供用于检索令牌的用户名和密码)。
这里的最佳做法是什么?
【问题讨论】:
标签: android oauth openid openid-connect