ファーストパーティアプリケーションの OAuth 2.0: 非公開クライアントのヘッドレスユーザー名とパスワードフロー
会社が開発したプラットフォーム外アプリケーションのユーザー名パスワードログインを設定するには、このヘッドレスユーザー名パスワードログインフローを使用します。このフローでは、ファーストパーティアプリケーション用 OAuth 2.0 ドラフト標準プロトコルを実装しています。このフローでは、ファーストパーティアプリケーションのフロントエンドログイン環境を完全に制御でき、Salesforce はユーザーを認証して保護されたリソースへのアクセス権を付与するバックエンド作業を処理します。このフローは、クライアント-サーバーアプリケーションなどの非公開クライアントでのみサポートされ、外部ユーザーでのみサポートされます。
必要なエディション
| 使用可能なインターフェース: Salesforce Classic および Lightning Experience の両方 |
| 使用可能なエディション: Enterprise Edition、Unlimited Edition、および Developer Edition |
非公開クライアントのヘッドレス ユーザ名パスワード ログインを設定するには、ヘッドレス ID API を実装するこのバージョンの認証コードとログイン情報フローを使用することもできます。どちらのフローも同じ使用事例 (Salesforce Platform 外のアプリケーションでのユーザー名とパスワードによるヘッドレスログイン) を実現します。ただし、いくつかの重要な違いに留意してください。
| ファーストパーティアプリケーションの OAuth | ヘッドレス ID API |
|---|---|
| 非公開クライアントでのみサポートされます。 | 公開クライアントと非公開クライアントでサポートされます。 |
| ファーストパーティアプリケーション用 OAuth 2.0 ドラフトプロトコルに準拠しています。 | OAuth 2.0 標準に基づいて構築された独自の Salesforce フロー。 |
| Salesforce 外部クライアントアプリケーションフレームワークでのみサポートされます。また、このフローの外部クライアントアプリケーションを設定するには、メタデータ API を使用するしかありません。 | Salesforce 外部クライアントアプリケーションと接続アプリケーションフレームワークの両方でサポートされます。 |
| セキュリティ上の理由により、このフローでは常にクライアントアテステーション JWT が必要です。Salesforce はクライアントアテステーション JWT を使用して、アプリケーションが会社によって開発されたことを検証します。 | セキュリティ上の理由により、認証または reCAPTCHA のいずれかが必要ですが、クライアントアテステーション JWT は必要ありません。 |
このフローを設定する前に、次の手順を実行します。
- ヘッドレス ID の前提条件を完了します。
- クライアントアテステーション JWT を生成します。
- Salesforce 外部クライアントアプリケーションを設定します。
- Experience Cloud 設定を行います。
デフォルトでは、ユーザーはユーザー名を入力してログインします。ユーザーにその他のオプションを提供するには、ヘッドレスユーザー検出を設定します。たとえば、ユーザーがメールアドレス、電話番号、または注文番号を入力するフローを作成します。「ユーザー名なしのヘッドレスログイン」を参照してください。
フローのしくみの概要を次に示します。
- ステップ 1: エンドユーザーがファーストパーティアプリケーションに移動し、ユーザー名とパスワードを使用してログインします。または、ヘッドレスユーザー検出を使用している場合は、メールアドレス、電話番号、注文番号などの識別子をパスワードと共に入力します。
- ステップ 2: ファーストパーティアプリケーションでクライアントアテステーション JWT を作成し、Proof Key for Code Exchange (PKCE) 拡張のパラメーターを生成します。
- ステップ 3: 認証コードを取得するために、ファーストパーティアプリケーションが Experience Cloud サイトの services/oauth2/v1/authorization_challenge エンドポイントにヘッドレス POST 要求を送信します。要求には、ユーザーのログイン情報と共にクライアントアテステーション JWT が含まれます。
- ステップ 4: ファーストパーティアプリケーションが要求を送信したことを確認するために、Salesforce はクライアントアテステーション JWT を検証し、他のパラメーターを検証します。
- (省略可能) ヘッドレスユーザー検出を使用している場合、Apex ハンドラーはログインに使用した識別子に基づいてユーザーを検索します。ユーザーのログイン情報が有効で、ユーザーが検証済みのメールアドレスまたは電話番号を持っている場合、ログインが続行されます。
- ステップ 5: 要求が成功すると、Salesforce は認証コードを返します。
- ステップ 6: コードをアクセストークンと交換するために、ファーストパーティアプリケーションが要求を /services/oauth2/token エンドポイントに送信します。
- ステップ 7: Salesforce がアクセストークンを含むトークン応答を返します。
- ステップ 8: ファーストパーティアプリケーションでアクセストークンを処理し、ユーザーのセッションを作成します。
- ステップ 9: エンドユーザーがログイン状態になり、保護された Salesforce リソースへのアクセス権が必要なアクションをアプリケーションで実行します。
- ステップ 10: ファーストパーティアプリケーションが Salesforce API への認証済みコールを実行します。
- ステップ 11: ユーザーがファーストパーティアプリケーションで Salesforce データにアクセスできるようになりました。
ステップ 1: エンドユーザーがファーストパーティアプリケーションを開いてログインする
エンドユーザーがログインしようとしているファーストパーティアプリケーションを開きます。アプリケーションにログインフォームが表示され、ユーザー名とパスワードの項目とログインボタンが示されます。Salesforce はこのログインフォームを提供していません。お客様が自由にデザインできます。ユーザーはユーザー名とパスワードを入力して、ログインボタンをクリックします。
ステップ 2: ファーストパーティアプリケーションによるクライアントアテステーション JWT の作成とcode_verifierおよびcode_challenge値の生成
アプリケーションがクライアント証明 JWT を作成します。
アプリケーションでは、認証コードの検証に使用される PKCE パラメーターの値も生成されます。
PKCE についての詳細は、Internet Engineering Task Force (IETF) が提供する仕様「RFC 7636: Proof Key for Code Exchange by OAuth Public Clients (OAuth 公開クライアントによるコード交換の証明鍵)」を参照してください。
RFC 7636 で定義された PKCE 仕様には、認証要求で送信できる、省略可能な code_challenge_method パラメーターも含まれています。このパラメーターで送信する値は、Salesforce では無視され、デフォルトの SHA256 になります。
ステップ 3: ファーストパーティアプリケーションが認証コードをヘッドレスで要求する
アプリケーションがブラウザーから、ヘッドレス POST 要求を介して、ユーザーのログイン情報と他のパラメーターを Experience Cloud サイトの services/oauth2/v1/authorization_challenge エンドポイントに送信します。
この要求に必要なヘッダーはありません。必要に応じて、このフローをヘッドレスゲストフローに接続するために、一意の訪問者 ID(UVID)値を含む JWT ベースのアクセストークンを含む Uvid-Hint ヘッダーを含めることができます。
| ヘッダー | 必須かどうか | 説明 |
|---|---|---|
Uvid-Hint
|
いいえ。アプリケーションでゲストユーザーフローを実装する場合、必要に応じてこのヘッダーを使用して、ゲストユーザーの ID に関連付けられた UVID が含まれる JWT ベースのアクセストークンを渡すことができます。 ヘッダーで |
アプリケーションによって生成されて完全に管理されるバージョン 4 のユニバーサル一意識別子 (UUID) である UVID 値を含む JWT ベースのアクセストークン。UVID でアクセストークンを取得するには、JWT ベースのアクセストークンを発行し、アプリケーションでヘッドレスゲストフローを実装できるように外部クライアントアプリケーションまたは接続アプリケーションを有効にする必要があります。 |
リクエストボディに次のパラメーターを含めます。
| パラメーター | 必須かどうか | 説明 |
|---|---|---|
code_challenge
|
外部クライアントアプリケーションで PKCE が必要な場合は必須です。このフローのセキュリティ機能を正しく機能させるには、常に PKCE を要求することを強くお勧めします。 | トークン要求で 認証要求で 認証要求で |
username
|
はい。 | ユーザーがログインフォームに送信したユーザー名。 |
client_id
|
はい。 | 外部クライアントアプリケーションのコンシューマー鍵。 |
password
|
はい。 | ユーザーがログインフォームに送信したパスワード。 |
client_assertion
|
はい。 | 生成したクライアントアテステーション JWT。外部クライアントアプリケーション用に設定された証明書によって署名されます。 |
recaptcha
|
次の条件が適用される場合は必須です。
|
ユーザーが reCAPTCHA チャレンジを完了したときに、Google reCAPTCHA API によって発行される暗号化されたトークン。 |
recaptchaevent
|
次の条件が適用される場合は必須です。
|
これらのサブパラメーターを含む JSON オブジェクト。
詳細は、Google の reCAPTCHA ドキュメントを参照してください。 |
scope
|
いいえ。 | 外部クライアントアプリケーションがアクセスできる保護されたリソースの種別を定義する権限。外部クライアントアプリケーションの作成時に範囲を割り当てると、認証フロー中に OAuth トークンに範囲が含まれます。 このパラメーターを使用して、外部クライアントアプリケーションに割り当てられた範囲のサブセットを要求します。このパラメーターを含めない場合、アプリケーションに割り当てられたすべての範囲が要求されます。 |
uvid_hint
|
いいえ。アプリケーションでゲストユーザーフローを実装する場合は、必要に応じてこのパラメーターを使用して、ゲストユーザーの ID に関連付けられた リクエストボディで |
プレーン リクエストボディで UVID を渡す代わりに、 |
login_hint
|
ヘッドレスユーザー検出 Apex ハンドラを使用している場合は必須です。 | Apex ハンドラーがユーザーの Salesforce アカウントを検索するために使用する識別子。たとえば、アプリケーションでユーザーの注文番号を収集し、login_hint パラメーターに渡します。login_hint 値が Apex ハンドラーに直接送信されます。 |
customdata
|
カスタムデータを処理するヘッドレスユーザー検出ハンドラーを使用している場合は必須です。たとえば、カスタムデータを処理するログインフローでもハンドラーを使用している場合、パスワードを忘れた場合のフローでカスタムデータを渡す必要があります。 それ以外の場合は省略可能ですが、ハンドラーがユーザーを見つけるのに役立ちます。 |
Apex ヘッドレス検出ハンドラーがユーザーの Salesforce アカウントを検索するために使用する追加データを含む JSON 文字列。たとえば、ユーザーのロケールに関する情報を渡します。 |
認証チャレンジエンドポイントへの要求の例を次に示します。
POST /services/oauth2/v1/authorization_challenge? HTTP 1.1
Host: MyExperienceCloudSite.my.site.com
username=janice.edwards@example.com&
password=*****&
client_assertion=******&
recaptcha=********&
scope=profile&
code_challenge=********
ステップ 4: Salesforce による要求の検証
Salesforce は最初に、client_asssertion パラメーターで渡された署名が外部クライアントアプリケーション用に設定された証明書の署名と一致することを確認して、クライアントアテステーション JWT を検証します。
クライアントアテステーション JWT が有効でない場合、Salesforce は invalid_attestation エラーを返します。最初に送信したすべてのパラメーターを使用して要求を再送信する必要があります。エラー応答の例を次に示します。
HTTP/1.1 403 Forbidden
Content-Type: application/json
Cache-Control: no-store
{
"error": "invalid_attestation",
"error_code": "client_attestation_failed"
}
クライアントアテステーション JWT が有効であっても、要求に他の問題があると、Salesforce は要求の問題点を示すエラー応答を返します。ユーザーが誤ったユーザー名またはパスワードを送信した場合に返される応答の例を次に示します。
HTTP/1.1 403 Forbidden
Content-Type: application/json
Cache-Control: no-store
{
"error": "authorization_required",
"auth_session": "uY29tL2F1d*****",
"error_code": "invalid_credentials"
}応答には、発行後 5 分間有効な auth_session パラメーターが含まれます。auth_session の有効期間中に、auth-session を使用して要求を再送信できます。再送信する修正バージョンには、要求が失敗する原因となったパラメーターの修正値のみを含めます。また、Salesforce では password が保存されないため、要求ごとにパスワードを再送信する必要があります。ただし、他のパラメーターについては、要求の失敗の原因でない場合は省略できます。これらのパラメーターは auth_session にリンクされているため、Salesforce はすでにこれらのパラメーターが送信されたことを認識しています。
auth_session にリンクされませんが、要求の失敗の原因でない限り、パラメーターなしで要求を再送信できます。一般的なエラーシナリオの例をいくつか紹介します。このリストは包括的ではありません。
- ユーザーが誤ったユーザー名またはパスワードを送信した。
username、password、およびauth_sessionのみを使用して要求を再送信します。 - reCAPTCHA トークンが正しくありませんでした。reCAPTCHA トークン、
password,、およびauth_sessionのみを使用して要求を再送信します。
認証セッションが発行されてから 5 分が経過すると、認証セッションは機能しなくなり、auth_session_invalid エラーが発生します。その場合は、最初に含めたすべてのパラメーターを使用して完全な要求を再送信します。
(省略可能) ヘッドレスユーザー検出ハンドラーによるユーザーの検索
ヘッドレスユーザー検出ハンドラを使用している場合、ハンドラは login_hint パラメーターと customdata パラメーターを使用して、関連付けられたユーザーを検索します。ハンドラーは、ユーザーのメールアドレスまたは電話番号が検証されていることを確認します。
ハンドラの例については、「Auth.HeadlessUserDiscoveryHandler」を参照してください。
ステップ 5: Salesforce が認証コードを返す
認証チャレンジ エンドポイントへの要求が成功すると(最初の試行か、auth_session を使用した数回の再試行かに関係なく)、Salesforce は認証コードを返します。成功した認証コード応答の例を次に示します。
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
{
"authorization_code": "uY29tL2F1d******"
}ステップ 6: アプリケーションが認証コードをアクセストークンと交換する
認証コードを取得すると、アプリケーションが要求を services/oauth2/token エンドポイントに送信します。
この要求にはヘッダーはありません。リクエストボディに次のパラメーターを含めます。
| パラメーター | 必須かどうか | 説明 |
|---|---|---|
code
|
はい。 | 認証サーバーは、認証コード (有効期間が短いトークン) を作成し、認証の成功後にクライアントに渡します。クライアントは、認証コードを認証サーバーに送信してアクセストークンと、必要に応じて更新トークンを取得します。 |
client_id
|
はい。 | 外部クライアントアプリケーションのコンシューマー鍵。 |
client_secret
|
はい。 | 外部クライアントアプリケーションのコンシューマーの秘密。このフローでは、アプリケーションが Salesforce にアクセスするために使用するパスワードとして機能します。 |
redirect_uri
|
はい。 | 認証に成功した後にユーザーがリダイレクトされる URL。リダイレクト URI は、外部クライアントアプリケーションの [コールバック URL] 項目の値のいずれかと一致している必要があります。それ以外の場合、承認は失敗します。この値は URL エンコードされている必要があります。 |
grant_type
|
はい。 | 安全な訪問者であることを証明するためにアプリケーションが提供できる検証の種別。このフローでは、値は authorization_code である必要があります。 |
code_verifier
|
外部クライアントアプリケーションで PKCE が必要な場合は必須です。このフローのセキュリティ機能を正しく機能させるには、常に PKCE を要求することを強くお勧めします。 | code 値の推測を困難にするために、高エントロピーの 128 バイトのランダムなデータを指定します。このパラメーターを設定すると、認証コードの傍受攻撃を防ぐのに役立ちます。この値は、https://datatracker.ietf.org/doc/html/rfc4648#section-5 で定義されている base64url でエンコードされている必要があります。 トークン要求で トークン要求で |
トークン要求の例を次に示します。
POST services/oauth2/token? HTTP 1.1
Host: MyExperienceCloudSite.my.site.com
code=********&
client_id=**********&
client_secret=*********&
redirect_uri=<callback_URL>&
grant_type=authorization_code&
code_verifier=*******ステップ 7: Salesforce によるアクセストークンの付与
アプリケーションのログイン情報を検証した後、Salesforce がアクセストークンを返します。JSON 形式のアクセストークン応答の例を次に示します。
{
"access_token":"*******************",
"sfdc_community_url":"https://MyDomainName.my.site.com",
"sfdc_community_id":"0DBxxxxxxxxxxxx",
"signature":"ts6wm/svX3jXlCGR4uu+SbA04M6qhD1SAgVTEwZ59P4=",
"scope":"openid api",
"id_token":"XXXXXX",
"instance_url":"https://yourInstance.salesforce.com",
"id":"https://yourInstance.salesforce.com/id/00Dxxxxxxxxxxxx/005xxxxxxxxxxxx",
"token_type":"Bearer",
"issued_at":"1667600739962"
}アクセストークン応答には、次のパラメーターが含まれます。
| パラメーター | 必須かどうか | 説明 |
|---|---|---|
access_token
|
はい。 | 外部クライアントアプリケーションがクライアントアプリケーションの代わりに保護されたリソースへのアクセスを要求するために使用する OAuth トークン。範囲の形式の追加権限にはアクセストークンが付随することがあります。 |
id
|
はい。 | ユーザーを識別し、ユーザーの詳細を照会するために使用できる ID URL。「ID URL」を参照してください。 |
id_token
|
いいえ。 | ユーザーの一意の識別子、トークンがいつ発行されたかを示すタイムスタンプなど、認証済みユーザーの属性が含まれる署名済みデータ構造。要求元のアプリケーションも識別されます。「OpenID Connect の仕様」を参照してください。 |
instance_url
|
はい。 | ユーザーの組織のインスタンスを示す URL。たとえば、https://yourInstance.salesforce.com/ です。 |
issued_at
|
はい。 | 署名が作成されたときのタイムスタンプ (UTC の 1970-01-01T0:0:0Z からのミリ秒数として表記)。 |
refresh_token
|
いいえ。 | Web サーバー、ユーザーエージェント、またはハイブリッドアプリケーショントークンフローから取得したトークン。この値は秘密です。適切な対策を講じて保護してください。このパラメーターは、refresh_token 範囲を使用して外部クライアントアプリケーションまたは接続アプリケーションが設定されている場合にのみ返されます。 |
signature
|
はい。 | client_secret で署名されている Base64 エンコードされた HMAC-SHA256 署名。署名には連結 ID と issued_at 値を含めることができます。これらを使用して ID URL がサーバーから送信された後に変更されていないことを確認できます。 |
sfdc_community_url
|
はい。 | Experience Cloud サイトの URL。 |
sfdc_community_id
|
はい。 | ユーザーの Experience Cloud サイト ID。 |
state
|
いいえ。 | クライアントが要求した状態。この値は、state パラメーターが元のクエリ文字列に含まれている場合にのみ含まれます。 |
token_type
|
はい。 | Bearer トークン種別。アクセストークンを含むすべての応答で使用します。 |
ステップ 8: アプリケーションがユーザーのセッションを作成する
アプリケーションがアクセストークン応答を受信してユーザーのセッションを作成します。
ステップ 9: ユーザーがログインしてアプリケーションでアクションを実行する
エンドユーザーがログイン状態になり、Salesforce データへのアクセス権を必要とするアクションをアプリケーションで実行します。たとえば、Salesforce に保存されている注文履歴を表示するボタンをクリックします。
ステップ 10: アプリケーションが Salesforce エンドポイントへの認証済みコールを実行する
ユーザーの Salesforce データにアクセスするために、アプリケーションはアクセストークンを使用して、Salesforce API などの保護されている Salesforce エンドポイントに認証されたコールを実行します。
ステップ 11: ユーザーが Salesforce データにアクセスできる
ユーザーはアプリケーションで、保護されている Salesforce データにアクセスできるようになりました。たとえば、注文履歴を表示できます。ユーザー側では、ログインからデータにアクセスするまでのプロセス全体が、アプリケーションを離れる必要がなく行われました。
