Параметры запроса

Ниже описано 2 сценария:

  1. Аутентификация в мобильном приложении Партнера через приложение Сбербанк Онлайн и через веб Сбер ID (App to App & App to Web).
  2. Бесшовный переход из мобильного приложения Сбербанк Онлайн в приложение Партнера (App to App SSO).

Получение кода авторизации

  1. Клиент в приложении Партнера нажимает кнопку входа по Сбер ID.
  2. Приложение Партнера делает запрос в back-end Партнера для получения параметров аутентификации (client_id, redirect_url, state, nonce).
  3. Приложение Партнера генерирует параметр code_verifier и хэширует его методом code_challenge_method (S256). В результате хэширования получается значение code_challenge.
  4. Мобильное приложение Партнера проверяет наличие на устройстве клиента приложения Сбербанк Онлайн. Если оно есть - запрашивает код авторизации через приложение Сбербанк Онлайн (по deeplink), если нет - запрашивает код авторизации путем перенаправления на веб-страницу Сбер ID https://online.sberbank.ru/CSAFront/oidc/authorize.do (get запрос) в отдельном браузере. В запросе указываются параметры client_id, scope, redirect_url, state, nonce, code_challenge, code_challenge_method.
  5. Клиент в приложении Сбербанк Онлайн/веб-странице Сбер ID подтверждает аутентификацию.
  6. В результате аутентификации Сбербанк Онлайн/веб-страница Сбер ID перенаправляет клиента в приложение Партнера по адресу, указанному в redirect_uri. В случае успеха возвращается код авторизации и state, в ином случае - ошибка.
Партнер для вызова аутентификации не должен использовать браузер, встроенный в приложение, который предоставляет приложению доступ к cookie, или содержимому веб-страниц. При открытии веб-страницы Сбер ID в браузере, встроенном в приложение, будет отображена страница-заглушка, сообщающая клиенту о небезопасности входа.

Для сценариев, в которых присутствует риск перехвата AuthCode необходимо использовать защиту PKCE (https://tools.ietf.org/html/rfc7636). По рекомендациям RFC 7636 для смягчения атак перехвата кода авторизации используется динамически создаваемое случайное значение - code_verifier. Данное значение должно быть уникальным для каждого запроса кода авторизации. Требования к генерации значения code_verifier(см. также https://tools.ietf.org/html/rfc7636#section-4.1):

  • Значение code_verifier - это высокоэнтропийная криптографическая случайная строка;
  • Строка генерируется с использованием допустимых символов [AZ] / [az] / [0- 9] / "-" / "." / "_" / "~";
  • Минимальная длина - 43 символа;
  • Максимальная длина - 128 символов.

Один из возможных алгоритмов: Партнер, используя подходящий генератор случайных чисел, создает последовательность длиной от 32 до 96 байт, которую затем кодирует способом base64url. Например, для 32-байтной последовательности [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 132, 141, 121] кодирование base64url в результате даст code_verifier в виде “dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk” (см. https://tools.ietf.org/html/rfc7636#appendix-B ).

Аутентификация в мобильном приложении Партнера через приложение Сбербанк Онлайн и через веб Сбер ID (App to App & App to Web)

Android. Запрос кода авторизации через deeplink

sberbankidlogin://sberbankid?client_id={client_id}&state={state}&scope={scope}&redirect_uri={redirect_uri}&code_challenge_method={S256}

Описание полей запроса смотри в таблице Описание полей запроса кода авторизации.

На экран авторизации в приложении Партнера необходимо добавить кнопку Войти через Сбер ID, при нажатии на которую инициируется запрос кода авторизации.

Получение кода авторизации

  1. Добавить ключи параметров в ваше приложение:

Формирование параметров запроса:

//Название ключей, для параметров запроса
private static final String CLIENT_ID = "client_id";
private static final String STATE = "state";
private static final String NONCE = "nonce";
private static final String SCOPE = "scope";
private static final String BROWSER = "package";
private static final String REDIRECT_URI = "redirect_uri";
private static final String CODE_CHALLENGE = "code_challenge";
private static final String CODE_CHALLENGE_METHOD = "code_challenge_method";
  1. Создать Uri с параметрами из п.1.

Пример

//Создание Uri с параметрам
 Uri uri = new Uri.Builder()
        .scheme(SCHEME_MP)
        .authority(HOST_MP)
        .appendQueryParameter(CLIENT_ID, clientID)
        .appendQueryParameter(STATE, state)
        .appendQueryParameter(NONCE, nonce)
        .appendQueryParameter(SCOPE, scope)
     .appendQueryParameter(REDIRECT_URI, redirectUri)
        .appendQueryParameter(CODE_CHALLENGE, codeChallenge)
        .appendQueryParameter(CODE_CHALLENGE_METHOD, codeChallengeMethod)
        .build();
  1. Проверить установлено ли приложение Сбербанк Онлайн

Пример

//Проверка, что приложение Сбербанк онлайн установлено на телефоне 
private boolean isSberbankDeeplinkCanBeHandle(Context context) {
    Uri testSberbankDeeplink = new Uri.Builder()
            .scheme(SCHEME_MP)
            .authority(HOST_MP)
            .build();
    Intent testSberbankIntent = new Intent(Intent.ACTION_VIEW, testSberbankDeeplink);
    return testSberbankIntent.resolveActivity(context.getPackageManager()) != null;
}
  1. Запросить код авторизации:
  2. если приложение Сбербанк Онлайн установлено, то его необходимо запустить для запроса кода авторизации

Пример

//Запуск приложения Сбербанк Онлайн
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

Пример:

//Замените хост и схему, чтобы использовать web версию для аутентификации
if (checkSbolIsNotInstalled(context)) {
    uri.buildUpon()
    .scheme("https")
    .authority("online.sberbank.ru")
    .appendEncodedPath("CSAFront/oidc/authorize.do")
    .appendQueryParameter("response_type", "code")
    .build();
}
  1. В результате аутентификации вернется deeplink, указанный в redirect_uri. Чтобы обработать диплинк, укажите в AndroidManifest.xml

Пример

<activity
    android:name="com.example.MainActivity"
    android:theme="@style/AppTheme.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data
            android:host="merchant_host"
            android:scheme="app" />

    </intent-filter>
</activity>

Host и scheme должны соответствовать redirect_uri.

Пример обратного deeplink

Положительный результат:
app://apphost?state=Jt2dvD9a9tmZ&code=0BC4A121-F75F-8A3B-BE7E-8C2412209B17
Негативный результат:
app://apphost?result=FAILURE&error_code=5&error={error}

Код ошибки 5 означает, что в запросе от приложения Партнера пришли некорректные данные. Также можно посмотреть описание возможных ошибок в таблице Типы возвращаемых ошибок. Если в ответе пришел error и не пришел код ошибки, то необходимо обрабатывать это как ошибку. Результат стоит проверять по наличию параметров state и code.

Схема запроса:

sberbankidexternallogin://sberbankid?client_id={client_id}&scope={scope}&state={state}&redirect_uri={redirect_uri}

Описание полей запроса смотри в таблице Описание полей запроса кода авторизации.На экран авторизации в приложении Партнера необходимо добавить кнопку Войти по Сбер ID, при нажатии на которую инициируется запрос кода авторизации.

Получение кода авторизации состоит из следующих шагов:

Первоначально в настройках проекта необходимо создать redirecturi по примеру: sberbankidexternallogin:/ , где merchantScheme должен соответствовать в info.plist/URL types/URL Scheme

Пример:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>sberbankinvestor</string>
<string>merchantApp</string>
<string>messenger</string>
<string>merchant</string>
</array>
</dict>
  1.  Проверить установлено ли приложение Сбербанк Онлайн.

Пример:

NSURL *URL = [NSURL URLWithString:@"sberbankidexternallogin://"];
BOOL appToAppEnabled = [[UIApplication sharedApplication]
canOpenURL:URL];
if (appToAppEnabled){
// Сценарий AppToApp
} else {
// Сценарий AppToWeb
}

3. Запросить код авторизации:

  • если приложение Сбербанк Онлайн установлено, то его необходимо запустить для запроса кода авторизации

Пример:

NSString *strURL = [NSString stringWithFormat:@"sberbankidexternallogin://sberbankid?%@=%@&%@=%@&%@=%@&%@=%@",
@"client_id", sbID.clienID,
@"scope", sbID.scope,
@"state", sbID.state,
@"nonce", sbID.nonce/*,
@"image_url", [imagePath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]]*/
];
if (sbID.PKCEEEnabled)
{
NSString *codeChallenge = [PKCEHelper generateCodeChallenge];
NSString *codeChallengeMethod = [PKCEHelper codeChallengeMethod];
strURL = [strURL stringByAppendingFormat:@"&code_challenge=%@&code_challenge_method=%@", codeChallenge, codeChallengeMethod];
}
strURL = [strURL stringByAppendingFormat:@"&%@=%@", @"redirect_uri", sbID.redirectURI];
NSURL *URL = [NSURL URLWithString:[strURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
[[UIApplication sharedApplication] openURL:URL];

Пример:

NSURLComponents *URLComponents = [NSURLComponents componentsWithString:@"https://online.sberbank.ru/CSAFront/oidc/sberbank_id/authorize.do"];
NSURLQueryItem *responseTypeQueryItem = [NSURLQueryItem queryItemWithName:@"response_type" value:responseType];
NSURLQueryItem *clientIDQueryItem = [NSURLQueryItem queryItemWithName:@"client_id" value:clientID];
NSURLQueryItem *stateQueryItem = [NSURLQueryItem queryItemWithName:@"state" value:state];
NSURLQueryItem *nonceQueryItem = [NSURLQueryItem queryItemWithName:@"nonce" value:nonce];
NSURLQueryItem *scopeQueryItem = [NSURLQueryItem queryItemWithName:@"scope" value:scope];
NSURLQueryItem *redirectURIQueryItem = [NSURLQueryItem queryItemWithName:@"redirect_uri" value:redirectURI];
NSURLQueryItem *codeChallengeQueryItem = [NSURLQueryItem queryItemWithName:@"code_challenge" value:codeChallenge];
NSURLQueryItem *codeChallengeMethodItem = [NSURLQueryItem queryItemWithName:@"code_challenge_method" value:codeChallengeMethod];
URLComponents.queryItems = @[responseTypeQueryItem, clientIDQueryItem, stateQueryItem, nonceQueryItem, scopeQueryItem, redirectURIQueryItem,
codeChallengeQueryItem, codeChallengeMethodItem
];
NSURL *URL = URLComponents.URL;
[[UIApplication sharedApplication] openURL:URL];

4. Обработка редиректа (по redirect_uri) происходит в методах AppDelegate.

Пример:

// < iOS 9
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
// >= iOS 9
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options

В выбранном методе происходит обработка redirect_uri, отправленного в запросе на получение кода авторизации

NSDictionary *dictParams = [self URLQueryParametersFoURL:url];
NSString *state = dictParams[@"state"];
NSString *code = dictParams[@"code"];
NSString *status = dictParams[@"status"];
if (status.length && [status isEqualToString:@"success"] && state.length && code.length) {
// Обработка успешного результата
}
else if ([status isEqualToString:@"fail"]) {
// Обработка не успешного результата с возможной ошибкой
}

Код ошибки 5 означает, что в запросе от приложения Партнера пришли некорректные данные. Также можно посмотреть описание возможных ошибок в таблице Типы возвращаемых ошибок. Если в ответе пришел error и не пришел код ошибки, то необходимо обрабатывать это как ошибку. Результат стоит проверять по наличию параметров state и code.

Описание полей запроса кода авторизации

№ п/п Наименование заголовка/поля Описание Обязательность поля Пример
1 response_type Указывается равным code Да code
2 client_type Указывается равным PRIVATE Нет PRIVATE
3 scope Наименование групп данных, на которые подписана система Партнера (выдается при регистрации системы в банке). Значение openid является обязательным и располагается на первой позиции. Разделитель – пробел. Да openid name maindoc email mobile
4 client_id Идентификатор системы Партнера, полученный партнером в личном кабинете после регистрации приложения. Да DA5278AC-A07F-C01A-B2D3-C231DBB2E20F
5 state Значение, включенное в запрос, которое также возвращается в ответе. Может быть строка любого контента. Для предотвращения подделки межсайтовых запросов используется генерируемое случайным образом уникальное значение. Да af0ifjsldkj
6 nonce Значение, сгенерированное внешней АС для предотвращения атак повторения. Это значение обычно представляет собой случайную уникальную строку или глобальный уникальный идентификатор, которые можно использовать для определения источника запроса. Ограничение по длине значения составляет 64 символа. Да n-0S6_WzA2Mj
7 redirect_uri Адрес страницы Партнера, на которую будет перенаправлен клиент после успешной аутентификации в системе банка. Временное ограничение: недопустимы символы “;” и “=“. Да iOS/Android deeplink: https://app://sberbankid
8 code_challenge Хэшированное значение секретного кода code_verifier Партнера (генерацию code_verifier см. выше в блоке «Важно»). Хэширование выполняется методом, указанным в code_challenge_method, в нашем случае – всегда S256, поэтому code_challenge = BASE64URL-ENCODE(SHA256 (ASCII (code_verifier))) (см. https://tools.ietf.org/html/rfc7636#section-4.2 ). Например, для code_verifier = “dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk” выполнение хэширования SHA256 этого значения в результате выдаст последовательность байтов [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 112, 249, 195], преобразование которой через Base64Url дает нам значение code_challenge = “E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM” (см. https://tools.ietf.org/html/rfc7636#appendix-B ). Нет E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
9 code_challenge_method Метод преобразования секретного кода code_verifier Партнера. Допустимым значением является S256. Нет S256

Бесшовный переход из мобильного приложения Сбербанк Онлайн в приложение Партнера (App to App SSO)

Внутри мобильного приложения Сбербанк Онлайн есть возможность разместить баннер (или ссылку), ведущую на мобильное приложение Партнера. Для того, чтобы клиент при переходе мог бесшовно (без ввода логина и пароля) войти по Сбер ID в мобильное приложение Партнера необходимо вызвать сценарий входа по Сбер ID в веб (App to App). Пример формирования запроса описан выше в сценарии (App to App).Для реализации сценария необходимо:Внутри мобильного приложения Сбербанк Онлайн предварительно разместить баннер (или ссылку) с помощью специалистов СбераПартнеру внедрить App2App вход по Сбер ID (описан в разделе 1)Партнеру внутри своего мобильного приложения реализовать сервис, который будет автоматически формировать и вызывать запрос кода авторизации (шаг 2 в сценарии ниже) Сценарий:Клиент внутри мобильного приложения Сбербанк Онлайн нажимает на какой-либо баннер (или ссылку);В результате клиент перенаправляется в мобильное приложение Партнера по deeplink (или universal link), например partner://auth?type=auto&source=StoryGD20&to=cabinet, где source и to - дополнительные параметры, по которым сервис Партнера определяет откуда пришел клиент и куда его нужно перенаправить после успешного входа (то есть какой адрес указать в параметре redirect_uri в запросе кода авторизации). Сбер ID эти параметры никак не использует и они не участвуют в запросе кода авторизации;Мобильное приложение Партнера по входным параметрам (type=auto) определяет, что нужно сформировать и вызвать запрос кода авторизации по deeplink. Пример запроса описан выше в сценарии App to App;В составе входных параметров присутствует sberIDRedirect, который вычитывается и декодируется стандартным url decoder (кодировка UTF-8). Партнер генерирует параметры OIDC стандартным образом, добавляет их к значению из параметра sberIDRedirect и запускает полученный диплинк;

Пример запроса:

[scheme://host из sberIDRedirect]?
 
&scope=openid name phones email
 
&client_id=7CA84F72-EEA3-D4EC-C535-A12A618A4C3C
 
&state=UhdlDQS6vG4m&nonce=TGfhfBxr5ak1
 
&redirect_uri=https%3A%2F%2F<redirect_point>%2Fcas%2Flogin

Мобильное приложение Партнера запрашивает код авторизации (перенаправляет клиента в мобильное приложение Сбербанк Онлайн);Клиент автоматически аутентифицируется в мобильном приложении Сбербанк Онлайн (по уже активной сессии), подтверждает согласие (если оно не активно);В результате успешного входа мобильное приложение Сбербанк Онлайн перенаправляет клиента в приложение Партнера по адресу, указанному в параметре redirect_uri, например partner://sberidauthtocabinet.При реализации данного сценария Партнеру необходимо учесть следующие случаи:Клиент уже аутентифицирован в мобильном приложении Партнера каким-либо другим способом. В этом случае клиенту нужно предложить связать учетные записи.

Заметили ошибку?

Выделите текст и нажмите Ctrl + Enter, чтобы сообщить нам о ней