Android/IOS 使用客户端凭据流进行秘密过期管理

Android/IOS Secret expiration management with client credentials flow

我想知道是否有任何管理移动设备中的秘密过期的策略。

在授权服务器允许移动客户端使用资源所有者密码流结合客户端凭据进行授权的情况下,客户端机密具有到期时间。

我至少看到有一些方法可以安全地将机密存储在 Android 应用程序上,但是,如何在不发布新版本应用程序的情况下管理机密过期?

我能想到的唯一方法是当您 运行 应用程序第一次连接到服务器并发送 phone 指纹时,服务器将仅在以下情况下发送文件fingerPrint 未在其数据库中列出,该文件包含当前日期和该日期的数字签名,因此用户不会更改其值。 每次您 运行 您通过应用 VerifySignature 方法检查日期和日期完整性的应用程序。

这就是我们在 OAuth Refresh Token Standards.

之后在我们的应用程序中所做的

第 1 步:您的 API 应该按照 here

所述发送标准身份验证令牌响应
 HTTP/1.1 200 OK
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache

 {
   "access_token":"2YotnFZFEjr1zCsicMWpAA",
   "token_type":"example",
   "expires_in":3600,
   "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
   "example_parameter":"example_value"
 }

第 2 步:将响应保存在共享 Preferences/Local Cache/Local 数据库中,我们使用了共享首选项(假设 accountToken 是 class 的对象,是从 Auth Token 的响应创建的)

SharedPreferences.Editor editor = getContext().getSharedPreferences("AUTH_PREFS_NAME", Context.MODE_PRIVATE).edit();
editor.putString("AUTH_ACCESS_TOKEN_KEY", accountToken.getAccess_token());
editor.putString("AUTH_REFRESH_TOKEN_KEY", accountToken.getRefresh_token());
editor.putLong("AUTH_EXPIRES_IN_KEY", accountToken.getExpires_in());
editor.putLong("AUTH_TIME_SAVED_KEY", ((int) (System.currentTimeMillis() / 1000)));
editor.commit();

第 3 步:每次您必须使用保存的访问令牌时,确保它没有过期

public boolean needsTokenRefresh(String accessToken) {
    if (accessToken == null || accessToken.length() == 0) {
        // no access token to refresh. Don't refresh.
        return false;
    }

    SharedPreferences pref = mContext.getSharedPreferences("AUTH_PREFS_NAME", Context.MODE_PRIVATE);
    String refreshToken = pref.getString("AUTH_REFRESH_TOKEN_KEY", null);
    if (refreshToken == null || refreshToken.length() == 0) {
        // no refresh token. Can't refresh.
        return false;
    }

    Integer timeSaved = pref.getInt("AUTH_TIME_SAVED_KEY", 0);
    if (timeSaved == 0) {
        // No recording of having saved the token. Don't refresh.
        return false;
    }

    long expiresIn = pref.getLong("AUTH_EXPIRES_IN_KEY", 0);
    int now = (int) (System.currentTimeMillis() / 1000);
    int timePassed = Math.abs(now - timeSaved);
    boolean expired = false;
    if (expiresIn <= timePassed) {
        expired = true;
    }
    return expired;
}

If needsTokenRefresh() returns false 然后使用保存的授权令牌。如果它 returns true 则转到下一步。

第 4 步:使用 grant_type 设置为 refresh_tokenstated in standards

再次进行身份验证调用

第 5 步:身份验证调用应 return 标准身份验证响应,如第 1 步中所述,并刷新令牌和新 refresh_token