質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Active Directory

Active Directoryは、 Windows Serverの機能の一つで、 マイクロソフトによって作られたディレクトリサービスです。 ネットワーク上に存在する様々なハードや利用者情報のアクセス権限などを一元管理が出来ます。

Azure

Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

3586閲覧

Azure APIのアクセストークン取得について

OkukawaRyoki

総合スコア16

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Active Directory

Active Directoryは、 Windows Serverの機能の一つで、 マイクロソフトによって作られたディレクトリサービスです。 ネットワーク上に存在する様々なハードや利用者情報のアクセス権限などを一元管理が出来ます。

Azure

Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2021/03/31 00:42

前提・実現したいこと

Azure APIのアクセストークンを取得したいのですが、なぜできないのか分かりません。。。

発生している問題・エラーメッセージ

AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. 翻訳 AADSTS9002326:クロスオリジントークンの引き換えは、「シングルページアプリケーション」クライアントタイプでのみ許可されます

環境

JavaScriptで叩いてHTMLに表示させるようなプログラムを組んでいます。
Azure ADの方ではサブスクリプションの作成、アプリを登録し権限なども付与しています。
アプリのリダイレクトURLは下記URLの制限をクリア(http://localhost/myApp)しているものを追加しており、シングルページアプリケーションのプラットフォームを選択しています。
また、叩く環境もリダイレクトURLに合わせてあります。

リダイレクトURLの制限について
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/reply-url

エラーの内容があまり理解できておらず、アプリのリダイレクトURLに追加すればいいのかな?と何となくでやりましたが、あっているのか分かりません。

叩きたいAPI

https://login.microsoftonline.com/テナント.onmicrosoft.com/oauth2/token

試したこと

アプリのリダイレクトURLにローカルホストの環境を追加
CORSなども拡張機能を使用してとりあえずクリアしています。

補足情報

自分的に思うことなのですが、アプリのリダイレクトURLはあくまでアプリのアクセストークンを取得できるURLを指定するだけで、ADは別?(アプリの方にもapiのエンドポイントがあったので)

apiの実装もほぼ初めてでAzure ADも詳しくないのでなんでも参考になる情報頂けると嬉しいです。。。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

シングルページアプリケーションを作成されているということで、良いでしょうか?
当該エラーはブラウザからCORSアクセス時に付与されるOriginヘッダが無いと発生するようです。
fetchのオプションにmode:'cors'を付与することでトークンが取得できると思います。
(もし、サーバ側でトークンを扱いたいのであれば、通常のWebアプリケーションフローで大丈夫です。)

下記、私が試したコードです。CLIENT_IDやテナント名を埋めていただき、CALLBACK_URIでアクセスできるように配置すれば動きます。
※AADに登録されているCALLBACK_URIと異なると、怒られます。
なお、エラーチェック等は省いています。

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf8"/> 5 <title>example</title> 6 </head> 7 <body> 8 <pre></pre> 9 <script> 10// 認可エンドポイント 11const AUTH_ENDPOINT = 'https://login.microsoftonline.com/<テナント名>.onmicrosoft.com/oauth2/v2.0/authorize'; 12// トークンエンドポイント 13const TOKEN_ENDPOINT = 'https://login.microsoftonline.com/<テナント名>.onmicrosoft.com/oauth2/v2.0/token'; 14// クライアントID 15const CLIENT_ID = '<クライアントIDを埋めてください>'; 16// リダイレクトURI 17const REDIRECT_URI = 'http://localhost:8080/'; 18// スコープ 19const SCOPE = 'https://graph.microsoft.com/User.Read'; 20// コードチャレンジ 本当はコードベリファイアから計算 (RFC 7636に記載のテスト用のものを利用) 21// [Appendix B. Example for the S256 code_challenge_method](https://tools.ietf.org/html/rfc7636#appendix-B) 22const CODE_CHALLENGE = 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM'; 23const CODE_CHALLENGE_METHOD = 'S256'; 24// コードチャレンジ 本当は都度生成 25// [Appendix B. Example for the S256 code_challenge_method](https://tools.ietf.org/html/rfc7636#appendix-B) 26const CODE_VERIFIER = 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'; // RFC 7636 27 28(async () => { 29 if (!location.hash || location.hash == '#') { 30 // hashが無い...コールバック前 31 32 const url = new URL(AUTH_ENDPOINT); 33 const params = url.searchParams; 34 35 // クエリパラメータへ追加 36 params.set('client_id', CLIENT_ID); 37 params.set('response_type', 'code'); 38 params.set('redirect_uri', REDIRECT_URI); 39 params.set('response_mode', 'fragment'); 40 params.set('scope', SCOPE); 41 params.set('code_challenge', CODE_CHALLENGE); 42 params.set('code_challenge_method', CODE_CHALLENGE_METHOD); 43 44 // 認可エンドポイントへ画面遷移 45 location.assign(url); 46 47 } else { 48 // 認可エンドポイントからのコールバック後 49 50 const hash = location.hash.slice(1); // '#'を取り除く 51 location.hash = ''; // URLバーの#以降をクリア 52 const params = new URLSearchParams(hash); 53 // 認可コード取得 54 const code = params.get("code"); 55 56 const body = new URLSearchParams(); 57 body.append('client_id', CLIENT_ID); 58 body.append('scope', SCOPE); 59 body.append('code', code); 60 body.append('redirect_uri', REDIRECT_URI); 61 body.append('grant_type', 'authorization_code'); 62 body.append('code_verifier', CODE_VERIFIER); 63 64 // トークン取得 65 const response = await fetch(TOKEN_ENDPOINT, { 66 method: 'POST', 67 mode: 'cors', // CORSでアクセス 68 body, 69 }); 70 const token = await response.json(); 71 document.querySelector('pre').textContent = JSON.stringify(token, null, 2); 72 } 73})(); 74 </script> 75 </body> 76</html> 77<!-- vim:set ts=2 sts=2 sw=2: -->

投稿2021/04/05 03:36

yskszk63

総合スコア161

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問