Android/IOS Secret expiration management with client credentials flow

℡╲_俬逩灬. 提交于 2019-12-08 13:46:12

问题


I'd like to know if there is any strategy for managing secret expiration in mobile devices.

In a scenario where an authorization server allows a mobile client to authorize against him using a resource owner password flow in combination with client credentials, with the client secrets having an expiration time.

I've seen there are ways to safely store secrets on Android apps at least, but, how do you manage the secret expiration without publishing a new version of the app?


回答1:


This is how we have done in our App following OAuth Refresh Token Standards.

Step 1: Your API should be sending a standard Auth Token Response as stated 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"
 }

Step 2: Save that response in Shared Preferences/Local Cache/Local Database, we used Shared Preferences (assuming accountToken is Object of class created from Response of 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();

Step 3: Each time you have to use saved Access Token, make sure it is not expired

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 then use the saved Auth Token. If it returns true then go to next step.

Step 4: Make Auth call again with grant_type set as refresh_token as stated in standards

Step 5: Auth call should return Standard Auth Response as described in Step 1 with token refreshed and new refresh_token




回答2:


the only way i can think of is when you run the app for the first time it connect to a server and send the phone fingerPrint, the server will send a file only if the fingerPrint is not listed in its database, The file contain current date and a digital signature for this date so the user wont change its value. and every time you run the app you check the date and the integrity of the date by applying a VerifySignature Method.



来源:https://stackoverflow.com/questions/46687329/android-ios-secret-expiration-management-with-client-credentials-flow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!