Android

时间:2016-11-15 16:01:56

标签: android oauth openid openid-connect

我正在开发一个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 当前正在应用程序中进行硬编码(虽然客户端凭据授权不是要在生产中启用,因此仍然需要提供用于检索令牌的用户名和密码。

这里最好的做法是什么?

1 个答案:

答案 0 :(得分:1)

我想我不能建议你如何使用Java编写代码,但是在使用PHP创建应用程序时我也遇到了一些使用refresh_token的麻烦,所以也许我的想法会帮助你做些什么。

起初我一直在寻找永不过期的refresh_token(比如在Google API中),所以我甚至可以硬编码并在我想创建新的access_token时使用。无论如何,在oAuth2中真的很难做到。所以我在这里找到了一个有趣的问题:

Why do access tokens expire?

它向我展示了使用refresh_token的其他一些方法。我已经设置了我的oAuth服务,它生成并在每次使用refresh_token获取新的access_token时返回一个新的refresh_token。那部分对我最有帮助:

https://bshaffer.github.io/oauth2-server-php-docs/grant-types/refresh-token/

我们有类似的东西:

$server = new OAuth2\Server($storage, array(
    'always_issue_new_refresh_token' => true, // this part
    'refresh_token_lifetime'         => 2419200,
));

在这种情况下,我有一个很长的refresh_token,我可以存储在某个地方,当我需要它时,我会用它来获得一个新的access_token,但响应也会为我提供一个新的refresh_token,我可以再次存储并在以后使用它获取新的access_token。

因此,在您的情况下,我认为最好的方法是每次使用refresh_token请求access_token时继续生成refresh_token。如果用户不再使用您的APP,我认为他应该再次授权自己。