Copilot Studio では、シングル サインオン (SSO) がサポートされています。 SSO は、Web サイト上のエージェントが、エージェントが展開されているページやアプリにすでにサインインしている場合、顧客をサインインできるようにします。
たとえば、エージェントは社内のイントラネットまたはユーザーが既にサインインしているアプリでホストされます。
Copilot Studio の SSO を構成するには、主に 5 つの手順があります。
Microsoft Entra IDを使用してエージェントの手動認証を有効にする
カスタム キャンバスのMicrosoft Entra IDでアプリ登録を作成します。
Microsoft Entra IDでエージェントのカスタム スコープを定義します。
カスタム スコープをエージェント構成に追加します。
カスタム キャンバスのクライアント側コードを構成して、SSO を有効にします。
前提条件
サポート対象のチャネル
次の表は、現在 SSO をサポートしているチャネルの詳細です。 Copilot Studio のアイデア フォーラム>で追加チャネル<のサポートを提案できます。
1 Teams チャネルを有効にしている場合は、Microsoft Entra ID ドキュメントに記載されている、Microsoft Teams のエージェント用のシングルサインオンの構成手順に従う必要があります。 そのページの指示に従って Teams SSO 設定を構成しないと、ユーザーは Teams チャネルを使用するときに常に認証に失敗します。
2 ライブ チャット チャネルのみがサポートされています。 詳細については、「 Dynamics 365 Customer Service。
カスタム Web サイト用のアプリ登録を作成する
SSO を有効にするには、2 つの個別のアプリ登録を作成する必要です。
-
認証アプリの登録 は、エージェントの Microsoft Entra ID ユーザー認証を可能にします。
- カスタム Web ページの SSO を有効にするキャンバス アプリの登録
セキュリティ上の理由から、エージェントとカスタム Web サイトの両方で同じアプリ登録を再利用することはお勧めしません。
Microsoft Entra ID によるユーザー認証の構成に関する記事の手順に従って、認証アプリの登録を作成します。
キャンバス アプリ用の登録として機能する、2 つ目のアプリ登録を作成します。
トークンの交換 URL の追加
Copilot Studio でMicrosoft Entra ID認証設定を更新するには、トークン交換 URL を追加して、アプリと Copilot Studio で情報を共有できるようにする必要があります。
認証アプリの登録ページの Azure ポータルで、Expose an API に移動します。
スコープの下で、クリップボードにコピー アイコンを選択します。
Copilot Studio の Settings のナビゲーション メニューで、Security を選択し、Authentication タイルを選択します。
トークンの交換 URL (SSO に必要)に、先ほどコピーしたスコープを貼り付けます。
保存を選びます。
認証アプリ登録ページのAzure ポータルで、Overview に移動します。
[要点] の下の [アプリケーション (クライアント) ID] の値をコピーします。
ナビゲーション バーで、[管理>API をExpose] を選択します。
承認済みクライアント アプリケーションでクライアント アプリケーションの追加を選択し、コピーしたクライアント ID を貼り付けます。
保存を選びます。
キャンバス アプリの登録を作成した後は、認証にアクセスし、プラットフォームの追加を選択します。
プラットフォームの構成 で プラットフォームの追加、次に SPA を選択します。
リダイレクト URI の下で、http://contoso.com/index.html などの Web ページの URL を入力します。
暗黙的な許可とハイブリッド フロー セクションで、アクセス トークン (暗黙的なフローに使用) と ID トークン (暗黙的およびハイブリッド フローに使用) の両方をオンにします。
設定を選択します。
エージェントのトークン エンドポイント URL を見つける
Copilot Studio でエージェントを開き、Channels を選択します。
モバイル アプリを選択します。
トークン エンドポイントの下で、コピーを選択します。
Web ページで SSO を構成する
重要
SharePointと Graph Connector のデータ ソースから AI によって生成された回答は、SSO 対応アプリのゲスト ユーザーには使用できません。
Copilot Studio GitHub リポジトリで提供されているコードを使用して、リダイレクト URL の Web ページを作成します。 GitHub リポジトリからコードをコピーし、次の手順に従って変更します。
Azure ポータルの Overview ページに移動し、キャンバス アプリの登録から Application (クライアント) ID と Directory (テナント) ID をコピーします。
Microsoft Authentication Library (MSAL) を構成するには:
-
clientId を アプリケーション (クライアント) ID に割り当てます。
-
authority を https://login.microsoftonline.com/ に割り当て、最後に ディレクトリ (テナント) ID を追加します。
例:
var clientApplication;
(function (){
var msalConfig = {
auth: {
clientId: '00001111-aaaa-2222-bbbb-3333cccc4444',
authority: 'https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
},
theURL 変数を、すでにコピーしたトークン エンドポイント URL に設定します。 例:
(async function main() {
var theURL = "https://<token endpoint URL>"
userId の値を編集して、カスタム接頭辞を含めます。 例:
var userId = clientApplication.account?.accountIdentifier != null ?
("My-custom-prefix" + clientApplication.account.accountIdentifier).substr(0, 64)
: (Math.random().toString() + Date.now().toString()).substr(0,64);
変更を保存。
SSO が正常に構成されたことを確認します。
エージェントをテストするときに、SSO が正常に構成 されていない 場合は、サインインするように求められます。これによって、チャット ウィンドウにコピーする必要がある検証コードが表示されます。
サインイン プロンプトが表示されたら、この手順のステップ 1 から 5 を正しく完了したか確認します。 SSO が正常に構成されている場合、サインインのプロンプトは表示されません。
注意
GitHub リポジトリのコードでは、ユーザーがサインイン ボタンを選択する必要があります。 運用環境では、ボタンの機能をページへの遷移など、より適切なイベントに置き換えることを検討してください。
関連するコンテンツ
技術的概要
次の図は、ユーザーが Copilot Studio にサインイン プロンプト (SSO) を表示せずにサインインする方法を示しています。
エージェント ユーザーは、サインイン トピックをトリガーする フレーズを入力します。 サインイン トピックは、ユーザーをサインインしてユーザーの認証されたトークン (User.AccessToken 変数) を使用するように設計されています。
Copilot Studio は、ユーザーが構成済みの ID プロバイダーでサインインできるようにサインイン プロンプトを送信します。
エージェントの カスタム キャンバス はサインイン プロンプトを遮断し、Microsoft Entra IDからオンビハーフオブ (OBO) トークンを要求します。 キャンバスはトークンをエージェントに送信します。
OBO トークンの受信時に、エージェントは OBO トークンを「アクセス トークン」に交換し、アクセス トークンの値を使用して AuthToken 変数を入力します。
IsLoggedIn 変数はこの時点でも設定されます。
カスタム キャンバスのMicrosoft Entra IDでアプリ登録を作成する
SSO を有効にするには、2 つの個別のアプリ登録が必要です:
重要
エージェントのユーザー認証とカスタム キャンバスの両方に同じアプリ登録を利用することはできません。
エージェントのキャンバス用アプリ登録を作成する
Azure ポータルにサインインします。
アイコンを選択するか、上部の検索バーで検索して、App registrations に移動します。
[新規登録] を選択します。
登録の名前を入力してください。 登録するキャンバスのエージェント名を使用し、「キャンバス」を含めることで、それを認証用のアプリ登録と区別するのに役立ちます。
たとえば、エージェントが "Contoso 営業ヘルプ" と呼ばれている場合、アプリ登録に "ContosoSalesCanvas" などの名前を付ける場合があります。
サポートされているアカウントの種類で、任意の組織のテナント (任意の Microsoft Entra ID ディレクトリ - マルチテナント) と個人の Microsoft アカウント (Skype、Xbox など) を選択します。
次のステップでその情報を入力するので、今回は リダイレクト URI セクションを空白のままにします。
登録 を選択します。
登録が完了した後、概要 ページが開きます。
マニフェストにアクセスします。
accessTokenAcceptedVersion が 2 に設定されていることを確認します。 そうでない場合は、2 に変更し、保存を選択します。
リダイレクト URL の追加
登録を開いた状態で、認証にアクセスし、プラットフォームの追加を選択します。
プラットフォームの構成ブレードで、Web を選択します。
リダイレクト URI で、チャット キャンバスがホストされているページに完全な URL を追加します。
暗示的な許可セクションで、ID トークンおよびアクセス トークン チェックボックスを選択します。
構成を選択して変更を確認します。
API アクセス許可に移動します。
<テナント名に管理者の承認を付与する>を選択してから、はいを選択します。
重要
ユーザーが各アプリケーションに対して同意する必要をなくすために、少なくともアプリケーション管理者またはクラウド アプリケーション管理者の役割を割り当てられた担当者は、アプリケーション登録に対してテナント全体にわたる同意を与えることができます。
エージェントのカスタム スコープを定義する
認証アプリ登録内でキャンバス アプリ登録用の API を公開することにより、カスタム スコープを定義します。
スコープ により、ユーザーと管理者の役割およびアクセス権を決定できます。
この手順では、認証用の認証アプリ登録とカスタム キャンバス用のアプリ登録の間に信頼関係が作成されます。
認証を構成したとき に作成したアプリ登録を開きます。
API アクセス許可に移動し、エージェントに適切なアクセス許可が追加されていることを確認してください。
<テナント名に管理者の承認を付与する>を選択してから、はいを選択します。
重要
ユーザーが各アプリケーションに対して同意する必要をなくすために、少なくともアプリケーション管理者またはクラウド アプリケーション管理者の役割を割り当てられた担当者は、アプリケーション登録に対してテナント全体にわたる同意を与えることができます。
API を公開するに移動してからスコープの追加を選択します。
スコープの名前と、ユーザーが SSO 画面にアクセスしたときに表示される表示情報を入力します。
[スコープの追加] を選択します。
[+ クライアント アプリケーションの追加] を選びます。
アプリケーション (クライアント) ID を、キャンバス アプリ登録の概要ページからクライアント ID フィールドに入力します。 作成した一覧表示スコープのチェックボックスを選択します。
アプリケーション追加を選択します。
Copilot Studio 認証構成ページの Token Exchange URL は、ボット フレームワークを介して要求されたアクセス トークンの OBO トークンを交換するために使用されます。
Copilot Studio は、実際の交換を実行するためにMicrosoft Entra IDを呼び出します。
Copilot Studio にサインインします。
認証を有効化するエージェントを選択したことを確認するには、上部メニューのエージェントアイコンを選択し、正しいエージェントを選択します。
ナビゲーション メニューの 設定 で セキュリティ を選択します。 次に、認証 カードを選択します。
[トークン交換 URL] フィールドに、エージェントの認証アプリ登録の [API の公開] ページから完全なスコープ URI を入力します。 URI の形式は api://1234-4567/scope.name です。
保存を選択してからエージェント コンテンツを公開します。
エージェントが配置されているカスタム キャンバス ページを更新して、サインイン カードのリクエストを受信し、OBO トークンを交換します。
<head> セクションの <script> タグに次のコードを追加して、Microsoft Authentication Library (MSAL) を構成します。
clientId をキャンバス アプリ登録用の アプリケーション (クライアント) ID で更新します。
<Directory ID> をディレクトリ (テナント) ID に置き換えます。 キャンバス アプリ登録の概要ページからこれらの ID を取得します。
<head>
<script>
var clientApplication;
(function () {
var msalConfig = {
auth: {
clientId: '<Client ID [CanvasClientId]>',
authority: 'https://login.microsoftonline.com/<Directory ID>'
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: false
}
};
if (!clientApplication) {
clientApplication = new Msal.UserAgentApplication(msalConfig);
}
} ());
</script>
</head>
次の <script> を <body> セクションに挿入します。 このスクリプトはメソッドを呼び出して resourceUrl を取得し、現在のトークンを OAuth プロンプトで要求されたトークンと交換します。
<script>
function getOAuthCardResourceUri(activity) {
if (activity &&
activity.attachments &&
activity.attachments[0] &&
activity.attachments[0].contentType === 'application/vnd.microsoft.card.oauth' &&
activity.attachments[0].content.tokenExchangeResource) {
// asking for token exchange with Microsoft Entra ID
return activity.attachments[0].content.tokenExchangeResource.uri;
}
}
function exchangeTokenAsync(resourceUri) {
let user = clientApplication.getAccount();
if (user) {
let requestObj = {
scopes: [resourceUri]
};
return clientApplication.acquireTokenSilent(requestObj)
.then(function (tokenResponse) {
return tokenResponse.accessToken;
})
.catch(function (error) {
console.log(error);
});
}
else {
return Promise.resolve(null);
}
}
</script>
次の <script> を <body> セクションに挿入します。
main メソッド内で、このコードによりエージェントの一意の識別子を用いて store に条件を追加します。 また固有の ID を、userId 変数として生成します。
エージェントの ID を使用して <BOT ID> を更新します。 Copilot Studio でエージェントの ID を確認するには、エージェントの Channels ページに移動し、Mobile アプリを選択します。
<script>
(async function main() {
// Add your BOT ID below
var BOT_ID = "<BOT ID>";
var theURL = "https://powerva.microsoft.com/api/botmanagement/v1/directline/directlinetoken?botId=" + BOT_ID;
const {
token
} = await fetchJSON(theURL);
var directline = await fetchJSON(regionalChannelSettingsURL).then(res=> res.channelUrlsById.directline);
const directLine = window.WebChat.createDirectLine({
domain: `${directline}v3/directline`,
token
});
var userID = clientApplication.account?.accountIdentifier != null ?
("Your-customized-prefix-max-20-characters" + clientApplication.account.accountIdentifier).substr(0, 64) :
(Math.random().toString() + Date.now().toString()).substr(0, 64); // Make sure this will not exceed 64 characters
const store = WebChat.createStore({}, ({
dispatch
}) => next => action => {
const {
type
} = action;
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'startConversation',
type: 'event',
value: {
text: "hello"
}
}
});
return next(action);
}
if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
const activity = action.payload.activity;
let resourceUri;
if (activity.from && activity.from.role === 'bot' &&
(resourceUri = getOAuthCardResourceUri(activity))) {
exchangeTokenAsync(resourceUri).then(function(token) {
if (token) {
directLine.postActivity({
type: 'invoke',
name: 'signin/tokenExchange',
value: {
id: activity.attachments[0].content.tokenExchangeResource.id,
connectionName: activity.attachments[0].content.connectionName,
token,
},
"from": {
id: userID,
name: clientApplication.account.name,
role: "user"
}
}).subscribe(
id => {
if (id === 'retry') {
// The agent was not able to handle the invoke, so display the oauthCard
return next(action);
}
// else: tokenexchange successful and we do not display the oauthCard
},
error => {
// an error occurred to display the oauthCard
return next(action);
}
);
return;
} else
return next(action);
});
} else
return next(action);
} else
return next(action);
});
const styleOptions = {
// Add styleOptions to customize Web Chat canvas
hideUploadButton: true
};
window.WebChat.renderWebChat({
directLine: directLine,
store,
userID: userID,
styleOptions
},
document.getElementById('webchat')
);
})().catch(err => console.error("An error occurred: " + err));
</script>
完全なサンプル コード
詳細については、MSAL を使用して完全なサンプル コードを見つけ、GitHub リポジトリに既に含まれている条件付きスクリプト格納。