Параметры запроса
Ниже описано 2 сценария:
- Аутентификация в мобильном приложении Партнера через приложение Сбербанк Онлайн и через веб Сбер ID (App to App & App to Web).
- Бесшовный переход из мобильного приложения Сбербанк Онлайн в приложение Партнера (App to App SSO).
Получение кода авторизации
- Клие нт в приложении Партнера нажимает кнопку входа по Сбер ID.
- Приложение Партнера делает запрос в back-end Партнера для получения параметров аутентификации (
client_id,redirect_url,state,nonce). - Приложение Партнера генерирует параметр
code_verifierи хэширует его методомcode_challenge_method(S256). В результате хэширования получается значениеcode_challenge. - Мобильное приложение Партнера проверяет наличие на устройстве клиента приложения Сбербанк Онлайн. Если оно есть - запрашивает код авторизации через приложение Сбербанк Онлайн (по deeplink), если нет - запрашивает код авторизации путем перенаправления на веб-страницу Сбер ID https://online.sberbank.ru/CSAFront/oidc/authorize.do (get запрос) в отдельном браузере. В запросе указываются параметры
client_id,scope,redirect_url,state,nonce,code_challenge,code_challenge_method. - Клиент в приложении Сбербанк Онлайн/веб-странице Сбер ID подтверждает аутентификацию.
- В результате аутентификации Сбербанк Онлайн/веб-страница Сбер 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, при нажатии на которую инициируется запрос кода авторизации.
Получение кода авторизации
- Добавить ключи параметров в ваше приложение:
Форми рование параметров запроса:
//Название ключей, для параметров запроса
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";
- Создать 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();
- Проверить установлено ли приложение Сбербанк Онлайн
Пример
//Проверка, что приложение Сбербанк онлайн установлено на телефоне
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;
}
- Запросить код авторизации:
- если приложение Сбербанк Онлайн установлено, то его необходимо запустить для запроса кода авторизации
Пример
//Запуск приложения Сбербанк Онлайн
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
- если не установлено, то необходимо запросить код авторизации путем перенаправления на веб-страницу Сбер ID https://online.sberbank.ru/CSAFront/oidc/authorize.do (get запрос) в отдельном браузере (подробнее можно узнать в разделе Параметры запроса).
Пример:
//Замените хост и схему, чтобы использовать web версию для аутентификации
if (checkSbolIsNotInstalled(context)) {
uri.buildUpon()
.scheme("https")
.authority("online.sberbank.ru")
.appendEncodedPath("CSAFront/oidc/authorize.do")
.appendQueryParameter("response_type", "code")
.build();
}
- В результате аутентификации вернется 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.
iOS. Запрос кода авторизации через deeplink
Схема запроса:
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>
- Проверить установлено ли приложение Сбербанк Онлайн.
Пример:
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];
- если не установлено, то необходимо запросить код авторизации путем перенаправления на веб-страницу Сбер ID https://online.sberbank.ru/CSAFront/oidc/authorize.do (get запрос) в отдельном браузере (подробнее можно узнать в разделе Параметры запроса.
Пример:
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.
При реализации данного сценария Партнеру необходимо учесть следующие случаи: Клиент уже аутентифицирован в мобильном приложении Партнера каким-либо другим способом. В этом случае клиенту нужно предложить связать учетные записи.