2017-10-11 71 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未在其數據庫中列出時發送文件,文件包含當前日期和該日期的數字簽名,因此用戶不會更改其值。 並且每次運行應用程序時,都會通過應用驗證簽名方法來檢查日期和日期的完整性。