Управление истечением срока действия секрета Android / IOS с потоком учетных данных клиента

Я хотел бы знать, есть ли какая-либо стратегия управления истечением срока действия секрета на мобильных устройствах.

В сценарии, когда сервер авторизации позволяет мобильному клиенту авторизоваться против него, используя поток паролей владельца ресурса в сочетании с учетными данными клиента, при этом секреты клиента имеют срок действия.

Я видел способы безопасного хранения секретов, по крайней мере, в приложениях для Android, но как вы управляете истечением срока действия секрета, не публикуя новую версию приложения?


person Miguel A. Arilla    schedule 11.10.2017    source источник


Ответы (2)


Именно так мы поступили в нашем приложении в соответствии с стандартами токенов обновления OAuth.

Шаг 1. Ваш API должен отправлять стандартный ответ токена аутентификации, как указано здесь

 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: Сохраните этот ответ в Shared Preferences / Local Cache / Local Database, мы использовали Shared Preferences (предполагая, что 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. Выполните вызов Auth еще раз с grant_type, установленным как refresh_token, как указано в стандартах

Шаг 5. Вызов аутентификации должен возвращать стандартный ответ аутентификации, как описано в шаге 1, с обновленным токеном и новым refresh_token

person adnanyousafch    schedule 22.10.2017
comment
Я думаю, вы забыли записать вызов, который сохраняет "AUTH_TIME_SAVED_KEY", на который вы полагаетесь, когда определяете, истек срок действия токена или нет, поэтому я взял на себя смелость добавить его для вас. :) В общем, вам, возможно, следует быть немного консервативным с этой меткой времени, поскольку задержка (обычная для мобильных устройств) может привести к тому, что сервер не примет ее, хотя ваш метод говорит, что срок ее действия не истек (вы проверяете только локально). Однако это крайний случай, и с ним можно справиться. - person Gero; 23.10.2017
comment
Я думаю, что пропустил это при усечении лишних битов. Спасибо за добавление. - person adnanyousafch; 23.10.2017
comment
Это решение спасло меня по-разному. Спасибо! Довольно прямолинейно и легко реализовать. - person coolDude; 27.07.2018

единственный способ, о котором я могу думать, - это когда вы запускаете приложение в первый раз, когда оно подключается к серверу и отправляет отпечаток пальца телефона, сервер отправит файл, только если отпечаток пальца не указан в его базе данных, файл содержит текущую дату и цифровая подпись для этой даты, чтобы пользователь не изменил ее значение. и каждый раз, когда вы запускаете приложение, вы проверяете дату и ее целостность, применяя метод VerifySignature.

person Abdulkarim Mak    schedule 18.10.2017