2017-10-11 30 views
0

我想知道是否有任何管理移动设备中的秘密到期的策略。带客户端凭证的Android/IOS秘密到期管理流程

在授权服务器允许移动客户端使用资源所有者密码流并结合客户端证书来授权他的情况下,客户端秘密具有到期时间。

我见过有很多方法可以安全地在Android应用上存储秘密,但是,如何在不发布新版本应用的情况下管理秘密到期?

回答

3

这就是我们在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:保存在共享偏好/本地缓存/本地数据库响应,我们使用的共享设定(假定accountToken在类的对象从身份验证令牌的响应)

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; 
} 

如果needsTokenRefresh()返回false然后使用保存的身份验证令牌。如果它返回true然后转到下一步。

第4步:再次验证调用与grant_type设定为refresh_token作为stated in standards

第5步:验证调用应该返回标准AUTH响应与令牌更新和新refresh_token

+2

步骤1的描述我想你忘记了在确定令牌是否过期时,记下保存您所依赖的''AUTH_TIME_SAVED_KEY''的调用,所以我冒昧地为您添加它。 :)一般来说,你应该对这个时间戳稍微保守一点,因为延迟(移动通用)可能导致服务器不接受它,尽管你的方法说它没有过期(你只能在本地检查)。这是一个极端的情况,虽然可以处理。 – Gero

+0

我想我错过了,而截断额外的位。感谢您的加入。 – adnanyousafch

1

我能想到的唯一方法是当您第一次运行应用程序时,它连接到服务器并发送手机fingerPrint,服务器将只在fingerPrint未在其数据库中列出时发送文件,文件包含当前日期和该日期的数字签名,因此用户不会更改其值。 并且每次运行应用程序时,都会通过应用验证签名方法来检查日期和日期的完整性。