Вы находитесь здесь:
Процесс носителя OAuth 2.0 JWT для интеграции между серверами
Иногда требуется авторизовать серверы для доступа к данным без интерактивного входа при каждом обмене информацией. Для этих случаев можно использовать процесс носителя веб-маркера OAuth 2.0 JSON (JWT). Этот поток использует сертификат для подписи запроса JWT и не требует явного взаимодействия с пользователем. Однако, этот поток требует предварительного утверждения клиентского приложения.
Требуемые версии
| Доступно в версиях: Salesforce Classic и Lightning Experience |
| Доступно в версиях: Все выпуски |
С помощью процесса маркера носителя OAuth 2.0 JWT клиент публикует JWT в конечной точке маркера OAuth Salesforce. Salesforce обрабатывает JWT, содержащий цифровую подпись, и выдает маркер доступа на основе предварительного утверждения приложения.
Данный пример отображает действия, выполненные в потоке.
- Служба отчетов начинает еженедельный пакетный отчет.
- Связанное приложение отправляет JWT в конечную точку маркера Salesforce. JWT позволяет предоставлять общий доступ к личным данным и сведениям о безопасности в доменах безопасности.
- Salesforce проверяет JWT на основе подписи посредством предварительно настроенного сертификата и дополнительных параметров.
- Если JWT действителен и связанное приложение предварительно утверждено, Salesforce выдает маркер доступа. Предварительное утверждение происходит одним из следующих способов:
- Если политика связанного приложения установлена на «Пользователи, допущенные администратором, предварительно авторизованы», можно использовать профили и наборы полномочий.
- Если политика связанного приложения установлена на «Все пользователи могут авторизовываться самостоятельно», можно использовать утверждение конечного пользователя и выдачу маркера обновления. Однако клиент не обязан иметь текущий или сохраненный маркер обновления. Клиент также не обязан передавать секрет клиента в конечную точку маркера.
Примечание Для обоих вариантов Salesforce выпускает новый маркер доступа, только если исходный маркер доступа содержит как минимум одну стандартную область, отличную от областиrefresh_token. - Связанное приложение использует маркер доступа для доступа к защищенным данным на сервере Salesforce.
- Служба отчетов извлекает авторизованные данные в ночной отчет.
Рассмотрим каждый этап процесса авторизации.
Создание JWT
Salesforce требует, чтобы JWT подписывался посредством RSA SHA256, использующего переданный сертификат в качестве секрета подписи. Прежде чем использовать данный поток авторизации, выполните данные действия.
- Загрузите сертификат X509 в Java-магазин ключей (JKS). Размер сертификата не может превышать 4 КБ. В таком случае попробуйте использовать файл в кодировке DER для уменьшения размера.
- Зарегистрируйте сертификат X509 для связанного приложения. Сертификат соответствует секретному ключу приложения. Когда связанное приложение сохраняется,
client_idиclient_secretсоздаются и назначаются приложению. - Создайте приложение, генерирующее JWT, подписанное личным ключом сертификата X509. Связанное связанное приложение использует сертификат для проверки подписи. JWT должна соответствовать общим правилам формата, указанным в https://tools.ietf.org/html/rfc7519.
Примечание Salesforce не требует утверждения кода JWT (JTI) в маркерах носителя JWT. Однако, если вы передаете требование JTI в маркер носителя JWT, Salesforce проверяет, что требование JTI не было отправлено ранее. Эта проверка предотвращает атаки повтора JWT.
Чтобы создать допустимый JWT, выполните данные действия.
- Сформируйте заголовок JWT со следующим форматом:
{"alg":"RS256"}. - Base64url кодирует заголовок JWT, как определено в http://tools.ietf.org/html/rfc4648#page-7. Результат аналогичен
eyJhbGciOiJSUzI1NiJ9. - Создайте набор утверждений JSON для JWT со следующими параметрами.
Ниже указан пример набора утверждений JSON для JWT.Параметр Описание issОтправитель должен содержать client_idOAuth связанного приложения, для которого вы зарегистрировали сертификат.audАудитория определяет сервер авторизации в качестве целевой аудитории. Сервер авторизации должен проверить, является ли он целевой аудиторией маркера.
Используйте URL-адрес сервера проверки подлинности для значения аудитории: https://login.salesforce.com, https://test.salesforce.com, или https://site.force.com/customers при внедрении для сайта Experience Cloud.
subЕсли вы внедряете этот поток для сайта Experience Cloud, тема должна содержать имя пользователя.
Для обратной совместимости можно использовать значение «Основная» (
prn) вместо значения «Тема» (sub). Если указаны оба параметра, используетсяprn.expДата и время истечения срока действия маркера, выраженное как количество секунд с 1970-01-01T0:0:0Z, измеренное в UTC. Salesforce разрешает 3-минутный буфер для искажения часов. Например, если время истечения срока действия установлено на 1 735 743 600 секунд или 1 января 2025 года в 15:00:00 UTC, маркер продолжает действовать до 15:03:00 UTC в эту дату. {"iss": "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQ ukXnVjzRgSuQqGn75NL7yfkQcyy7", "sub": "my@email.com", "aud": "https://login.salesforce.com", "exp": "1333685628"} - Base64url кодирует набор утверждений JWT без разрывов строк. Например:
eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz Njg1NjI4In0= - Создайте строку для зашифрованного заголовка JWT и зашифрованного набора утверждений JWT в этом формате.
В данном примере выделен зашифрованный заголовок JWT.encoded_JWT_Header + "." + encoded_JWT_Claims_SeteyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz Njg1NjI4In0= - Загрузите сертификат X509 из JKS.
- Подпишите итоговую строку посредством RSA SHA256.
- Создайте строку из данного этапа в следующем формате.
В данном примере выделена подпись в кодировке base64.existing_string + "." + base64_encoded_signatureeyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz Njg1NjI4In0=.iYCthqWCQucwi35yFs-nWNgpF5NA_a46fXDTNIY8ACko6BaEtQ9E6h4Hn1l_pcwcK I_GlmfUO2dJDg1A610t09TeoPagJsZDm_H83bsoZUoI8LpAA1s-2aj_Wbysqb1j4uDToz 480WtEbkwIv09sIeS_-QuWak2RXOl1Krnf72mpVGS4WWSULodgNzlKHHyjAMAHiBHIDNt 36y2L2Bh7M8TNWiKa_BNM6s1FNKDAwHEWQrNtAeReXgRy0MZgQY2rZtqT2FcDyjY3JVQb En_CSjH2WV7ZlUwsKHqGfI7hzeEvVdfOjH9NuaJozxvhPF489IgW6cntPuT2V647JWi7ng
Данный код Java является простым примером создания маркера носителя JWT.
import org.apache.commons.codec.binary.Base64;
import java.io.*;
import java.security.*;
import java.text.MessageFormat;
public class JWTExample {
public static void main(String[] args) {
String header = "{\"alg\":\"RS256\"}";
String claimTemplate = "'{'\"iss\": \"{0}\", \"sub\": \"{1}\", \"aud\": \"{2}\", \"exp\": \"{3}\", \"jti\": \"{4}\"'}'";
try {
StringBuffer token = new StringBuffer();
//Encode the JWT Header and add it to our string to sign
token.append(Base64.encodeBase64URLSafeString(header.getBytes("UTF-8")));
//Separate with a period
token.append(".");
//Create the JWT Claims Object
String[] claimArray = new String[5];
claimArray[0] = "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQukXnVjzRgSuQqGn75NL7yfkQcyy7";
claimArray[1] = "my@email.com";
claimArray[2] = "https://login.salesforce.com";
claimArray[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
claimArray[4]=<JTI>
MessageFormat claims;
claims = new MessageFormat(claimTemplate);
String payload = claims.format(claimArray);
//Add the encoded claims object
token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8")));
//Load the private key from a keystore
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("./path/to/keystore.jks"), "keystorepassword".toCharArray());
PrivateKey privateKey = (PrivateKey) keystore.getKey("certalias", "privatekeypassword".toCharArray());
//Sign the JWT Header + "." + JWT Claims Object
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(token.toString().getBytes("UTF-8"));
String signedPayload = Base64.encodeBase64URLSafeString(signature.sign());
//Separate with a period
token.append(".");
//Add the encoded signature
token.append(signedPayload);
System.out.println(token.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}Маркер доступа запроса
Для запроса маркера доступа связанное приложение публикует запрос маркера в конечной точке маркера экземпляра Salesforce. Она содержит JWT в сообщении.
Данный пример отображает образец запроса маркера.
POST /services/oauth2/token HTTP/1.1
Host: login.example.com
Content-Type: application/x-www-form-urlencoded
grant_type= urn:ietf:params:oauth:grant-type:jwt-bearer&
assertion=eyJpc3MiOiAiM01WRz...[omitted for brevity]...ZTДобавьте следующие параметры в сообщение.
| Параметр | Описание |
|---|---|
grant_type
|
Используйте данные значения для типа предоставления: urn:ietf:params:oauth:grant-type:jwt-bearer. |
assertion
|
Утверждение является целым значением JWT. |
format
|
(Дополнительно) Используйте для указания ожидаемого формата возврата. Этот параметр переопределяет заголовок запроса. Поддерживаются следующие форматы.
|
Параметр области
Невозможно указать области в потоке маркера носителя JWT. Области выдаются в соответствии с политикой «Разрешенные пользователи» связанного приложения или параметрами управления API-доступом вашей организации, как показано в таблице ниже.
| Параметр | Результат |
|---|---|
| Политика разрешенных пользователей: Все пользователи могут авторизовываться самостоятельно | После успешной авторизации области, возвращенные с маркером доступа, извлекаются из областей предыдущих утверждений. |
| Политика разрешенных пользователей: Пользователи, допущенные администратором, предварительно авторизованы | Стандартные и настраиваемые области, назначенные связанному приложению, возвращаются вместе с маркером доступа. |
| Управление доступом к API: Добавление связанных приложений в список разрешенных в организации | Стандартные и настраиваемые области, назначенные связанному приложению, возвращаются вместе с маркером доступа. Если вы добавляете связанные приложения в список разрешенных в вашей организации и не получаете ожидаемых областей, выполните данные действия.
|
Salesforce предоставляет маркер доступа
Запросы потока носителя утверждения OAuth 2.0 JWT и SAML рассматривают все предыдущие утверждения пользователя, содержащие маркер обновления. Если Salesforce находит совпадающие утверждения, он объединяет значения утвержденных областей. Salesforce потом выдает маркер доступа. Если Salesforce не находит предыдущие утверждения, содержащие маркер обновления или любые доступные утвержденные области, запрос не выполняется как несанкционированный.
После успешной проверки экземпляр Salesforce отправляет ответ связанному приложению. Ответ маркера для процесса маркера носителя OAuth 2.0 JWT соответствует формату процесса кода авторизации, хотя маркер обновления не выпускается.
Данный пример отображает ответ Salesforce.
{"access_token":"00Dxx0000001gPL!AR8AQJXg5oj8jXSgxJfA0lBog.
39AsX.LVpxezPwuX5VAIrrbbHMuol7GQxnMeYMN7cj8EoWr78nt1u44zU31
IbYNNJguseu",
"scope":"web openid api id","instance_url":"
https://yourInstance.salesforce.com","id":"
https://yourInstance.salesforce.com
/id/00Dxx0000001gPLEAY/005xx000001SwiUAAS","token_type":"Bearer"}Данные параметры находятся в тексте ответа.
| Параметр | Описание |
|---|---|
access_token |
Маркер OAuth, используемый связанным приложением для запроса доступа к защищенному ресурсу от имени клиентского приложения. Маркер доступа может сопровождаться дополнительными полномочиями в виде областей. |
token_type |
Тип Bearer маркера, используемый для всех ответов, содержащих маркер доступа. |
scope |
Области выдаются в соответствии с политикой «Разрешенные пользователи» связанного приложения или параметрами управления API-доступом вашей организации. См. Параметр scope. |
instance_url |
URL-адрес экземпляра организации пользователя. Например: https://yourInstance.salesforce.com/. |
id |
URL-адрес удостоверения, который может использоваться для идентификации пользователя и запроса дополнительных сведений о нем. См. URL-адреса удостоверения. |
sfdc_site_url |
Если пользователь является участником сайта Experience Cloud, предоставляется URL-адрес сайта. |
sfdc_site_id |
Если пользователь является участником сайта Experience Cloud, ему предоставляется код сайта. Для сайтов Experience Cloud этот поток содержит значение "sfdc_site_id" в конечной точке маркера. Этот код сайта потенциально требуется в запросах Connect REST API. |
Доступ к защищенным данным
После получения access_token связанным приложением оно может передать его в качестве маркера носителя в запросе заголовка авторизации. Данный пример отображает вызов REST API сайтам Experience Cloud:
https://site.force.com/customers/services/data/v32.0/ -H
"Authorization: Bearer 00D50000000IehZ\!AQcAQH0dMHZfz972Szmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1E6 LYUfiDUkWe6H34r1AAwOR8B8fLEz6n04NPGRrq0FM"

