Сбер ID
Документация

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

Ниже описаны 2 сценария взаимодействия:

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

  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 ).

1. Аутентификация в мобильном приложении Партнера через приложение Сбербанк Онлайн и через веб Сбер 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}

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

На экран авторизации в приложении Партнера необходимо добавить кнопку Войти через Сбер 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";

2. Создать 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();

3. Проверить установлено ли приложение Сбербанк Онлайн.

Пример
//Проверка, что приложение Сбербанк онлайн установлено на телефоне
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;
}

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

  • если приложение Сбербанк Онлайн установлено, то его необходимо запустить для запроса кода авторизации
Пример
//Запуск приложения Сбербанк Онлайн
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
  • если не установлено, то необходимо запросить код авторизации путем перенаправления на веб-страницу Сбер ID https://online.sberbank.ru/CSAFront/oidc/authorize.do (get запрос) в отдельном браузере. (подробнее можно узнать в разделе 1.1.1.1. Параметры запроса).
Пример
//Замените хост и схему, чтобы использовать web версию для аутентификации
if (checkSbolIsNotInstalled(context)) {
uri.buildUpon()
.scheme("https")
.authority("online.sberbank.ru")
.appendEncodedPath("CSAFront/oidc/authorize.do")
.appendQueryParameter("response_type", "code")
.build();
}

5. В результате аутентификации вернется 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 означает, что в запросе от приложения Партнера пришли некорректные данные. Также можно посмотреть описание возможных ошибок в Таблице 8. Типы возвращаемых ошибок

Если в ответе пришел error и не пришел код ошибки, то необходимо обрабатывать это как ошибку.

Результат стоит проверять по наличию параметров state и code.

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

Схема запроса
sberbankidexternallogin://sberbankid?client_id={client_id}&scope={scope}&state={state}&redirect_uri={redirect_uri}

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

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

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

1. Первоначально в настройках проекта необходимо создать 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>

2. Проверить установлено ли приложение Сбербанк Онлайн.

Пример
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 означает, что в запросе от приложения Партнера пришли некорректные данные. Также можно посмотреть описание возможных ошибок в Таблице 8. Типы возвращаемых ошибок

Если в ответе пришел error и не пришел код ошибки, то необходимо обрабатывать это как ошибку.

Результат стоит проверять по наличию параметров state и code.

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

№ п/п

Наименование заголовка/поля

Описание

Обязательность поля

Пример

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

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

Внутри мобильного приложения Сбербанк Онлайн есть возможность разместить баннер (или ссылку), ведущую на мобильное приложение Партнера.

Для того, чтобы клиент при переходе мог бесшовно (без ввода логина и пароля) войти по Сбер ID в мобильное приложение Партнера необходимо вызвать сценарий входа по Сбер ID в веб (App to App). Пример формирования запроса описан выше в сценарии (App to App).

Для реализации сценария необходимо:

  1. Внутри мобильного приложения Сбербанк Онлайн предварительно разместить баннер (или ссылку) с помощью специалистов Сбера
  2. Партнеру реализовать внедрить App2App вход по Сбер ID (описан в разделе 1)
  3. Партнеру внутри своего мобильного приложения реализовать сервис, который будет автоматически формировать и вызывать запрос кода авторизации (шаг 2 в сценарии ниже)

Сценарий:

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

При реализации данного сценария Партнеру необходимо учесть следующие случаи:

  1. Клиент уже аутентифицирован в мобильном приложении Партнера каким-либо другим способом. В этом случае клиенту нужно предложить связать учетные записи.