Microsoft Identity Platform OAuth で構成された OAuth のアクセストークン検証 概要 Microsoft Identity Platform OAuth フローを使用した SMTP および/または IMAP メールアカウントの構成 の最終手順は、Authorize Email Account Access UI アクションを使用してアクセストークンおよびリフレッシュトークンを取得することです。対応するトークンを受け取り、Test Connection が成功していることを確認した後は、メールの受信および送信が機能することが期待されます。しかし、場合によってはそうならず、問題の診断に役立つ明確なエラーが表示されないことがあります。 要約:提供されている Scripts - Background を使用して、受信したアクセストークンを検証してください。 この問題は、メールアカウントへのアクセスを承認する Microsoft アカウントが誤っていることに起因するケースが多いことが確認されています。 例えば、ユーザーが Microsoft SSO を使用して ServiceNow インスタンスにログインしている場合や、同じブラウザー内で Microsoft セッション(例:Outlook または Office)が既に存在する場合、Authorize Email Account Access UI アクションが実行された際に、そのアクティブなセッションがブラウザーによって自動的に使用されます。その結果、本来の IMAP/SMTP アカウントではなく、ユーザー自身のアカウントがメールアカウントアクセスの承認に使用されます。 例えば、次のメールアカウントは、servicedesk@vbcpn.onmicrosoft.com Microsoft アカウントを IMAP メールボックスとして使用するように構成されています: ログイン中のユーザー AdeleV@vbcpn.onmicrosoft.com は SSO ユーザーです。そのため、ユーザー Adele Vance が上記の IMAP アカウントに対して Authorize Email Account Access UI アクションをクリックしてメールアカウントアクセスを承認しようとすると、Microsoft はブラウザー内の Adele のアクティブセッションを使用します。その結果、受信されるトークンはアクセスを承認したアカウント、つまり AdeleV@vbcpn.onmicrosoft.com のトークンになるため、servicedesk@vbcpn.onmicrosoft.com IMAP アカウントからメールを取得できなくなります。 このため、 KB0816072: の手順 6 を厳密に守ることを推奨します: 「個人アカウントが Microsoft SSO ログインによって使用されないようにするため、シークレット/プライベートウィンドウとローカルログイン(必要に応じて side_door.do)を使用する必要があります。メールアカウントのユーザー名/認証情報を入力し、自身の認証情報は使用しないでください。」 「既に Azure にログインした状態で承認を実行した場合、ポップアップウィンドウは表示されず、承認が成功したように見える場合があります。しかし、インスタンスはメールアカウント用ではなく、自身の認証情報に対するアクセストークンを受け取ります。」 理想的には、メールアカウントのメールアドレスを入力するための Microsoft の「サインイン」プロンプトが表示される必要があります: 受信したアクセストークンを検証するために、以下で提供されている Scripts - Background を使用できます。 Scripts - Background 以下の Scripts - Background は、メール統合向けに Microsoft Identity Platform を使用して構成された OAuth のアクセストークンを検証します。検証が失敗した場合は、出力の「Next Steps」で解決策が提案されます。 説明 ナビゲーターメニューから、All > System Definition > Scripts - Background に移動します。以下で提供されているスクリプトをコピー&ペーストします。メールアカウントの sys_id を指定します。例: var email_account = "d94b4a7b3b78a210378b9d1d16e45a67"; グローバル スコープでスクリプトを実行します。 // ====== [ Access Token validation for OAuth configured with Microsoft Identity Platform ] ====== // Note: Run in Global Scope // Related KB: KB2071947 // Specify SysID of the Email Account var email_account = "__SYS_ID__"; //sys_id of [sys_email_account] /** =================================== // DO NOT EDIT BELOW THIS LINE // =================================== */ // Glide Records var email_gr = new GlideRecord("sys_email_account"); var oauth_cred = getAccessToken(); var instance_name = gs.getProperty("glide.servlet.uri"); var output_string = "\n\r======================================================================================\n" + "Access Token validation for OAuth configured with Microsoft Identity Platform\n" + "--------------------------------------------------------------------------------------\n\r"; if (email_gr.get(email_account)) { var email_user = email_gr.getValue("user_name"); var email_type = email_gr.getValue("type").toUpperCase(); var authorization_instruction = '!!!IMPORTANT!!! - Make sure you provide the credential for the Microsoft Account "' + email_user + '" during the authorization process. It is recommended to use incognito mode and login as a local admin user so that you do not already have an active Microsoft session in the browser. Ideally you should receive Microsoft prompt to put in the credential and grant the authorization for the account "' + email_user + '"'; if (oauth_cred) { var decrypted_token = parseJwt(oauth_cred.gr.token_received.getDecryptedValue()); //gs.print(JSON.stringify(decrypted_token)); var oauth_app_gr = new GlideRecord("oauth_entity"); oauth_app_gr.get(oauth_cred.gr.getValue("peer")); var scopes = decrypted_token.scp.split(" "); // output_string += 'Email Account:\t"' + email_gr.getValue("name") + '"\n'; output_string += '\tUser name:\t' + email_user + '\n'; output_string += '\tType:\t\t' + email_type + '\n'; output_string += '\tAuthentication:\t' + email_gr.getValue("authentication") + '\n'; output_string += '\tLink:\t\t' + instance_name + 'sys_email_account.do?sys_id=' + email_account + '\n\r\n\r'; output_string += 'Access Token:\n'; output_string += '\tIssued on:\t' + new Date(decrypted_token.iat * 1000) + '\n'; output_string += '\tExpires on:\t' + new Date(decrypted_token.exp * 1000) + '\n'; output_string += '\tUPN:\t\t' + decrypted_token.upn + '\n'; output_string += '\tName:\t\t' + decrypted_token.name + '\n'; output_string += '\tID Type:\t' + decrypted_token.idtyp + '\n'; output_string += '\tScopes:\t\t' + scopes.join(", ") + '\n'; output_string += '\tAudience:\t' + decrypted_token.aud + '\n'; output_string += '\tLink:\t\t' + instance_name + 'oauth_credential.do?sys_id=' + oauth_cred.gr.getValue("sys_id") + '\n'; output_string += '\tOAuth App:\t"' + oauth_app_gr.getValue("name") + '":\n'; output_string += '\t\t\t' + instance_name + 'oauth_entity.do?sys_id=' + oauth_app_gr.getValue("sys_id") + '\n\r\n\r'; if (email_user.toLowerCase() === (decrypted_token.upn).toLowerCase()) { output_string += 'SUCCESS:\tCongratulations! ' + email_type + ' Email Account "' + email_gr.getValue("name") + '" is configured correctly.\n\t\tUser name "' + email_user + '" matches UPN "' + decrypted_token.upn + '" in the token.\n'; } else { output_string += 'ERROR:\t' + email_type + ' Email Account "' + email_gr.getValue("name") + '" with User name "' + email_user + '" DOES NOT match UPN "' + decrypted_token.upn + '" in the token.\n'; output_string += '\tPlease re-authorize using the Microsoft account "' + email_user + '".\n\r'; output_string += "Next Steps:\n" output_string += "\t1.\tDelete the respective tokens from the following list:\n\t\t" + instance_name + "oauth_credential_list.do?requestor_id=" + oauth_cred.requestor_profile + "\n\r"; output_string += '\t2.\tGet fresh pair of tokens for Email Account "' + email_gr.getValue("name") + '" by using UI Action "Authorize Email Account Access" under Related Links:\n'; output_string += '\t\t' + instance_name + 'sys_email_account.do?sys_id=' + email_account + '\n\r'; output_string += '\t\t' + authorization_instruction + '\n\r'; output_string += "\t3.\tRun this script again to make sure the correct tokens are received. Once confirmed, email should be working as expected.\n\r"; } } else { output_string += "ERROR: \tAccess token is not found. Please authorize Email account to receive the tokens.\n\r"; output_string += '\t'+authorization_instruction + '\n\r'; } } else { output_string += "ERROR:\tEmail account with sys_id " + email_account + " is not found. Please provide a valid sys_id.\n\r"; } // Output gs.print(output_string); // Helpers /** * Returns JWT Token JSON Payload * @param {string} token - Decrypted JWT Token String */ function parseJwt (token) { var base64Url = token.split('.')[1]; var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); var jsonPayload = decodeURIComponent(GlideStringUtil.base64Decode(base64).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); return JSON.parse(jsonPayload); } /** * Returns an object with OAuth Credential Record and Requestor Profile Sys_ID */ function getAccessToken () { var reqProf_gr = new GlideRecord("oauth_requestor_profile"); reqProf_gr.addQuery("requestor_id", email_account); reqProf_gr.query(); if (reqProf_gr.next()) { var oauth_cred_gr = new GlideRecord("oauth_credential"); oauth_cred_gr.addQuery("oauth_requestor_profile", reqProf_gr.getValue("sys_id")); oauth_cred_gr.addQuery("type", "access_token"); oauth_cred_gr.orderByDesc("sys_updated_on"); oauth_cred_gr.setLimit(1); oauth_cred_gr.query(); if (oauth_cred_gr.next()) { return { gr: oauth_cred_gr, requestor_profile: reqProf_gr.getValue("sys_id") } ; } else { return; } } return; } 出力 このスクリプトは、Microsoft から受信した JWT (アクセストークン) をデコードし、メールアカウントの ユーザー名 と照合します。 1.例:無効なトークン ====================================================================================== Access Token validation for OAuth configured with Microsoft Identity Platform -------------------------------------------------------------------------------------- Email Account: "Microsoft Azure IMAP" User name: servicedesk@vbcpn.onmicrosoft.com Type: IMAP Authentication: oauth2 Link: https://emp.service-now.com/sys_email_account.do?sys_id=d94b4a7b3b78a210378b9d1d16e45a67 Access Token: Issued on: Thu Apr 17 2025 22:25:09 GMT-0700 (PDT) Expires on: Thu Apr 17 2025 23:32:46 GMT-0700 (PDT) UPN: AdeleV@vbcpn.onmicrosoft.com Name: Adele Vance ID Type: user Scopes: IMAP.AccessAsUser.All, SMTP.Send Audience: https://outlook.office.com Link: https://emp.service-now.com/oauth_credential.do?sys_id=cd2064a82b096610c286f216d891bfd2 OAuth App: "Microsoft Azure Mail": https://emp.service-now.com/oauth_entity.do?sys_id=9ff60a373b78a210378b9d1d16e45a00 ERROR: IMAP Email Account "Microsoft Azure IMAP" with User name "servicedesk@vbcpn.onmicrosoft.com" DOES NOT match UPN "AdeleV@vbcpn.onmicrosoft.com" in the token. Please re-authorize using the Microsoft account "servicedesk@vbcpn.onmicrosoft.com". Next Steps: 1. Delete following tokens: https://emp.service-now.com/oauth_credential_list.do?requestor_id=78e0bd4c2bc9e210c286f216d891bff7 2. Get fresh pair of tokens for Email Account "Microsoft Azure IMAP" by using UI Action "Authorize Email Account Access" under Related Links: https://emp.service-now.com/sys_email_account.do?sys_id=d94b4a7b3b78a210378b9d1d16e45a67 !!!IMPORTANT!!! - Make sure you provide the credential for the Microsoft Account "servicedesk@vbcpn.onmicrosoft.com" during the authorization process. It is recommended to use incognito mode and login as a local admin user so that you do not already have an active Microsoft session in the browser. Ideally you should receive Microsoft prompt to put in the credential and grant the authorization for the account "servicedesk@vbcpn.onmicrosoft.com" 3. Run this script again to make sure the correct tokens are received. Once confirmed, email should be working as expected. 2.例:有効なトークン ====================================================================================== Access Token validation for OAuth configured with Microsoft Identity Platform -------------------------------------------------------------------------------------- Email Account: "Microsoft Azure IMAP" User name: servicedesk@vbcpn.onmicrosoft.com Type: IMAP Authentication: oauth2 Link: https://emp.service-now.com/sys_email_account.do?sys_id=d94b4a7b3b78a210378b9d1d16e45a67 Access Token: Issued on: Thu Apr 17 2025 22:51:32 GMT-0700 (PDT) Expires on: Fri Apr 18 2025 00:09:56 GMT-0700 (PDT) UPN: servicedesk@vbcpn.onmicrosoft.com Name: Service Desk ID Type: user Scopes: IMAP.AccessAsUser.All, SMTP.Send Audience: https://outlook.office.com Link: https://emp.service-now.com/oauth_credential.do?sys_id=53266c202b496610c286f216d891bfa8 OAuth App: "Microsoft Azure Mail": https://emp.service-now.com/oauth_entity.do?sys_id=9ff60a373b78a210378b9d1d16e45a00 SUCCESS: Congratulations! IMAP Email Account "Microsoft Azure IMAP" is configured correctly. User name "servicedesk@vbcpn.onmicrosoft.com" matches UPN "servicedesk@vbcpn.onmicrosoft.com" in the token.