<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Azure | きいちログ</title>
	<atom:link href="https://wptech.kiichiro.work/tag/azure/feed/" rel="self" type="application/rss+xml" />
	<link>https://wptech.kiichiro.work</link>
	<description>WordPressとかAWSとかPHPとか</description>
	<lastBuildDate>Tue, 15 Jul 2025 09:36:32 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Laravel Starter Kits × WorkOSでEntra IDとSSOしたときの記録</title>
		<link>https://wptech.kiichiro.work/21jheu6bf8/</link>
		
		<dc:creator><![CDATA[むらおか]]></dc:creator>
		<pubDate>Tue, 15 Jul 2025 09:36:32 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Entra ID]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://wptech.kiichiro.work/?p=3849</guid>

					<description><![CDATA[目次 はじめに準備LaravelアプリケーションEntra ID側の準備とSAML接続ハマったポイントアプリケーションへのアクセス権がなくて拒否される (AADSTS50105)ドメインの設定漏れでSign in画面がル [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">はじめに</a></li><li><a href="#toc2" tabindex="0">準備</a><ol><li><a href="#toc3" tabindex="0">Laravelアプリケーション</a></li><li><a href="#toc4" tabindex="0">Entra ID側の準備とSAML接続</a></li></ol></li><li><a href="#toc5" tabindex="0">ハマったポイント</a><ol><li><a href="#toc6" tabindex="0">アプリケーションへのアクセス権がなくて拒否される (AADSTS50105)</a></li><li><a href="#toc7" tabindex="0">ドメインの設定漏れでSign in画面がループする</a></li><li><a href="#toc8" tabindex="0">属性のマッピング不正でログインに失敗する</a></li></ol></li><li><a href="#toc9" tabindex="0">さいごに</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">はじめに</span></h2>



<p>先日、Laravel 12 から Breeze と Jetstream の代わりに Starter Kits がサポートされたということを知りました。Starter Kits では WorkOS が公式にサポートされ、WorkOS 経由の SSO が比較的簡単に導入できるようになっていました。</p>




<a rel="noopener" href="https://laravel.com/starter-kits" title="Starter Kits - Laravel - The PHP Framework For Web Artisans" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img decoding="async" src="https://laravel.com/images/og/laravel-starter-kits.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Starter Kits - Laravel - The PHP Framework For Web Artisans</div><div class="blogcard-snippet external-blogcard-snippet">Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing ...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://laravel.com/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">laravel.com</div></div></div></div></a>




<a rel="noopener" href="https://laravel.com/docs/12.x/starter-kits" title="Starter Kits - Laravel 12.x - The PHP Framework For Web Artisans" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img decoding="async" src="https://laravel.com/images/og/laravel-docs-12.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Starter Kits - Laravel 12.x - The PHP Framework For Web Artisans</div><div class="blogcard-snippet external-blogcard-snippet">Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing ...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://laravel.com/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">laravel.com</div></div></div></div></a>



<p>せっかくなので Laravel Breeze で作ったアプリを Starter Kits を利用して作り直し、認証を WorkOS に寄せて Entra ID で SSO ログインをしてみました。実際にやってみると、WorkOS 側で拒否されるドメインがあったり、Entra ID 側の設定でログインに失敗するといったことがあり、結構なハマりポイントが多かったです。</p>



<p>今回は、導入までにハマったポイントを中心に記録を残していきます。</p>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-check block-box">
<p>WorkOS は、Google や Microsoft などのサービスを使ったソーシャルログインや SAML 認証で SSO を実現できる認証プロバイダーです。WorkOS を利用するには WorkOS アカウントが必要です。</p>




<a rel="noopener" href="https://workos.com" title="WorkOS — Your app, Enterprise Ready." class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://cdn.prod.website-files.com/621f54116cab10f6e9215d8b/627321b887917b110d342e2b_homepage.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">WorkOS — Your app, Enterprise Ready.</div><div class="blogcard-snippet external-blogcard-snippet">Developer APIs/SDKs for Enterprise Ready features like Single Sign-On, Directory Sync, Audit Logging, and more. Get star...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://workos.com" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">workos.com</div></div></div></div></a>
</div>



<h2 class="wp-block-heading"><span id="toc2">準備</span></h2>



<h3 class="wp-block-heading"><span id="toc3">Laravelアプリケーション</span></h3>



<p><code>laravel</code> コマンドをあらかじめインストールしておきます。<code>laravel new</code> で新しい Laravel プロジェクトを対話形式で作成できます。このとき、認証プロバイダーを選択できるので WorkOS を選んでおきます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code> ┌ Which authentication provider do you prefer? ────────────────┐
 │   ○ Laravel&#39;s built-in authentication                        │
 │ › ● WorkOS (Requires WorkOS account)                         │
 └──────────────────────────────────────────────────────────────┘</code></pre></div>



<p>WorkOS の API を利用するために <code>.env</code> も編集しておきます。各値は WorkOS のダッシュボードから確認できます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>WORKOS_CLIENT_ID=xxxx
WORKOS_API_KEY=xxxx
WORKOS_REDIRECT_URL=&quot;http://localhost:8000/authenticate&quot;</code></pre></div>



<h3 class="wp-block-heading"><span id="toc4">Entra ID側の準備とSAML接続</span></h3>



<p>Entra ID 側で WorkOS と SAML 接続できるように設定をしておきます。手順はドキュメントの通りで大丈夫です。</p>




<a rel="noopener" href="https://workos.com/docs/integrations/entra-id-saml" title="Entra ID SAML (formerly Azure AD) – Integrations – WorkOS Docs" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://og-images.workos.com/api/docs/?t=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjYXRlZ29yeSI6IkludGVncmF0aW9ucyIsInRpdGxlIjoiRW50cmEgSUQgU0FNTCAoZm9ybWVybHkgQXp1cmUgQUQpIiwiZGVzY3JpcHRpb24iOiJMZWFybiBob3cgdG8gY29uZmlndXJlIGEgY29ubmVjdGlvbiBFbnRyYSBJRCB2aWEgU0FNTCIsImlhdCI6MTc1MjA3ODY0OH0.GBl9X3yNSCpCh78HRqAaMD3klfQb9VZJDgRfNaKrDvA" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Entra ID SAML (formerly Azure AD) – Integrations – WorkOS Docs</div><div class="blogcard-snippet external-blogcard-snippet">Learn how to configure a connection Entra ID via SAML.</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://workos.com/docs/integrations/entra-id-saml" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">workos.com</div></div></div></div></a>



<p>ACS URL と SP Entity の場所が若干わかりづらいですが、Organizations から対応するものを選択して View connections ボタンを押下した先にあります (執筆当時)。</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="166" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/3cdf05bb6012e22c0373e0b2b343b056-1024x166.png" alt="Azure SSO の organization の設定画面。Authentication のエリアに Single Sign-On ブロックがあり、View connection ボタンがある。" class="wp-image-3894" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/3cdf05bb6012e22c0373e0b2b343b056-1024x166.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/3cdf05bb6012e22c0373e0b2b343b056-300x49.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/3cdf05bb6012e22c0373e0b2b343b056-768x125.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/3cdf05bb6012e22c0373e0b2b343b056-1536x249.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/3cdf05bb6012e22c0373e0b2b343b056-2048x332.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="200" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/a0a9f54e9a52c6a8f8247663ed908919-1024x200.png" alt="Service Provider Details のブロックに SP Entity ID, ACS URL, SP Metadata が表示されている。" class="wp-image-3897" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/a0a9f54e9a52c6a8f8247663ed908919-1024x200.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/a0a9f54e9a52c6a8f8247663ed908919-300x59.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/a0a9f54e9a52c6a8f8247663ed908919-768x150.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/a0a9f54e9a52c6a8f8247663ed908919-1536x301.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/a0a9f54e9a52c6a8f8247663ed908919-2048x401.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>UI は度々変更になるようですので、見当たらなければ根気よく探す必要があります。</p>



<h2 class="wp-block-heading"><span id="toc5">ハマったポイント</span></h2>



<h3 class="wp-block-heading"><span id="toc6">アプリケーションへのアクセス権がなくて拒否される (AADSTS50105)</span></h3>



<p>アプリのログイン画面 (または AuthKit) でメールアドレスを入力して送信すると、以下のようなメッセージが表示されます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>AADSTS50105: Your administrator has configured the application HOGE SAML App (&#39;xxxxx&#39;) to block users unless they are specifically granted (&#39;assigned&#39;) access to the application. The signed in user &#39;foo@bar.example.com&#39; is blocked because they are not a direct member of a group with access, nor had access directly assigned by an administrator. Please contact your administrator to assign access to this application.</code></pre></div>



<p>これは、ログインしようとしたユーザーに当該アプリケーションへのアクセスが許可されていないことに起因します。</p>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50105-user-not-assigned-role" title="エラー AADSTS50105 - サインインしているユーザーがアプリケーションのロールに割り当てされていません。" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://learn.microsoft.com/en-us/media/open-graph-image.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">エラー AADSTS50105 - サインインしているユーザーがアプリケーションのロールに割り当てされていません。</div><div class="blogcard-snippet external-blogcard-snippet">Microsoft Entra SSO を使用して SAML ベースの構成済みアプリにサインインするときにAADSTS50105 エラーが発生する問題について説明します。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50105-user-not-assigned-role" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>Entra 管理センターまたは Azure ポータルからユーザーを追加することで解消ができるはずです。</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="437" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/93666232d5217bfed963101834ddff81-1024x437.png" alt="" class="wp-image-3910" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/93666232d5217bfed963101834ddff81-1024x437.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/93666232d5217bfed963101834ddff81-300x128.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/93666232d5217bfed963101834ddff81-768x328.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/93666232d5217bfed963101834ddff81-1536x656.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/93666232d5217bfed963101834ddff81-2048x875.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><span id="toc7">ドメインの設定漏れでSign in画面がループする</span></h3>



<p>WorkOS で SSO を利用するには、事前にドメインの検証と設定が必要です。この設定が漏れていると Sign in 画面から先に進めずループしてしまう挙動を示すことがあります。</p>



<p>ドメインの検証方法には、次の2つがあります。</p>



<ul class="wp-block-list">
<li>Self-serve Domain Verification</li>



<li>Manual Domain Verification</li>
</ul>



<p>詳しくは公式ドキュメントをご覧ください。</p>




<a rel="noopener" href="https://workos.com/docs/user-management/domain-verification/manual-domain-verification" title="Domain Verification – AuthKit – WorkOS Docs" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://og-images.workos.com/api/docs/?t=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjYXRlZ29yeSI6IkF1dGhLaXQiLCJ0aXRsZSI6IkRvbWFpbiBWZXJpZmljYXRpb24iLCJkZXNjcmlwdGlvbiI6IlZlcmlmeSBvcmdhbml6YXRpb24gZG9tYWlucyBmb3Igc2VjdXJlIGF1dGhlbnRpY2F0aW9uIGFuZCBwcm92aXNpb25pbmciLCJpYXQiOjE3NTI0NDI3NTl9.ALGVuXT5rGp7Z0W_mHsesVdWSkJNxC3e16J8oDYUpOA" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Domain Verification – AuthKit – WorkOS Docs</div><div class="blogcard-snippet external-blogcard-snippet">Verify organization domains for secure authentication and provisioning.</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://workos.com/docs/user-management/domain-verification/manual-domain-verification" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">workos.com</div></div></div></div></a>



<p>Manual Domain Verification を利用する場合、既に Entra ID などで所有が確認されたカスタムドメインを、WorkOS の設定に手動で追加します。</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="314" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/b3684cfc898ab16bc696b6244a8d36aa-1024x314.png" alt="" class="wp-image-3923" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/b3684cfc898ab16bc696b6244a8d36aa-1024x314.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/b3684cfc898ab16bc696b6244a8d36aa-300x92.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/b3684cfc898ab16bc696b6244a8d36aa-768x236.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/b3684cfc898ab16bc696b6244a8d36aa-1536x471.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/b3684cfc898ab16bc696b6244a8d36aa-2048x628.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>ここでは所有が確認できるドメインを入力するので、<code>gmail.com</code> や <code>outlook.com</code> などの <code>public consumer domain</code> を入力しようとすると拒否されます。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="492" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/e12c23da18e887cb64deb7cbe61829e5-1024x492.png" alt="" class="wp-image-3932" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/e12c23da18e887cb64deb7cbe61829e5-1024x492.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/e12c23da18e887cb64deb7cbe61829e5-300x144.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/e12c23da18e887cb64deb7cbe61829e5-768x369.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/e12c23da18e887cb64deb7cbe61829e5.png 1224w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><span id="toc8">属性のマッピング不正でログインに失敗する</span></h3>



<p>ログインに失敗すると、Notifications に以下のログが残る場合があります。</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="398" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/06f1c8289ab1f8b22d7cf6aebeaf5eda-1024x398.png" alt="" class="wp-image-3940" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/06f1c8289ab1f8b22d7cf6aebeaf5eda-1024x398.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/06f1c8289ab1f8b22d7cf6aebeaf5eda-300x117.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/06f1c8289ab1f8b22d7cf6aebeaf5eda-768x299.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/06f1c8289ab1f8b22d7cf6aebeaf5eda-1536x597.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/06f1c8289ab1f8b22d7cf6aebeaf5eda.png 1630w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>同様に Admin Email 宛に以下のようなメッセージも届いているかと思います。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>Single Sign-On failed for XXXXXX

Your foo.example.com connection received invalid user attributes and failed to authenticate a user.
 
Why this might happen
 
The user attributes are misconfigured in Entra ID (Azure AD).
A single user is misconfigured in Entra ID (Azure AD). (Check the received attributes below).
 
How to fix this
 
Verify that attribute mapping is correct in the Entra ID (Azure AD) dashboard.</code></pre></div>



<p>このエラーは、idP (今回の場合 Entra ID) から返却される attribute が WorkOS 側で期待しているものと異なっていることを示しています。</p>




<a rel="noopener" href="https://workos.com/docs/reference/sso/profile" title="API Reference – WorkOS Docs" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://og-images.workos.com/api/docs/?t=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjYXRlZ29yeSI6IkRvY3MiLCJ0aXRsZSI6IkFQSSBSZWZlcmVuY2UiLCJkZXNjcmlwdGlvbiI6IkNvZGUgc25pcHBldHMgYW5kIHR5cGUgZGVmaW5pdGlvbnMgZm9yIHRoZSBXb3JrT1MgY2xpZW50IGxpYnJhcmllcyIsImlhdCI6MTc1MjUzNTk5OX0.BQz8GOrNy5GXy9HrECck8Z-Jcu-BLJz7fLWSr2VZ5cY" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">API Reference – WorkOS Docs</div><div class="blogcard-snippet external-blogcard-snippet">Code snippets and type definitions for the WorkOS client libraries.</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://workos.com/docs/reference/sso/profile" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">workos.com</div></div></div></div></a>



<p>WorkOS 側で期待している属性値と Entra ID 側から送っている属性がマッチしていることを確認します。</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="409" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/d2a46a061d48ce1ccc2a38c2b6de1a83-1024x409.png" alt="" class="wp-image-3949" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/d2a46a061d48ce1ccc2a38c2b6de1a83-1024x409.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/d2a46a061d48ce1ccc2a38c2b6de1a83-300x120.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/d2a46a061d48ce1ccc2a38c2b6de1a83-768x307.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/d2a46a061d48ce1ccc2a38c2b6de1a83-1536x614.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/d2a46a061d48ce1ccc2a38c2b6de1a83-2048x819.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">WorkOS Attribute mapping</figcaption></figure>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="663" src="https://wptech.kiichiro.work/wp-content/uploads/2025/07/9e957d994777d28c8e8bf4c8ce9665a3-1024x663.png" alt="" class="wp-image-3952" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/07/9e957d994777d28c8e8bf4c8ce9665a3-1024x663.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/9e957d994777d28c8e8bf4c8ce9665a3-300x194.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/9e957d994777d28c8e8bf4c8ce9665a3-768x497.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/9e957d994777d28c8e8bf4c8ce9665a3-1536x994.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/07/9e957d994777d28c8e8bf4c8ce9665a3.png 1598w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Entra 管理センター 属性とクレーム</figcaption></figure>



<p>WorkOS 側で required となっている項目については、Entra ID 側で設定されていないとキー毎何も返さなくなるので、設定しておく必要があります。特に Starter Kits を利用する場合は姓名が必須になっているので注意が必要です。</p>



<p>また、姓名を漢字などのマルチバイト文字で登録すると何故か返って来ないという現象がありました (これについては未解決です)。</p>



<h2 class="wp-block-heading"><span id="toc9">さいごに</span></h2>



<p>本記事では、Laravel Starter Kit で WorkOS を利用し、Microsoft Entra ID と SAML SSO を組み合わせた際に直面した問題とその対処法をまとめました。これが実際のプロジェクトで導入しようとしている方々の助けになれば幸いです。</p>



<p>今回紹介したものは、WorkOS 特有のハマりポイントもありましたが、Entra ID や SAML の仕様で躓いた部分もありました。私自身が SAML への理解が浅いということが露呈した結果ではあります。精進します。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Microsoft Certified: Azure Fundamentals (AZ-900) 合格までにやったことを振り返る</title>
		<link>https://wptech.kiichiro.work/16fmxdyyjh/</link>
		
		<dc:creator><![CDATA[むらおか]]></dc:creator>
		<pubDate>Wed, 22 Jan 2025 15:24:26 +0000</pubDate>
				<category><![CDATA[その他]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Microsoft]]></category>
		<guid isPermaLink="false">https://wptech.kiichiro.work/?p=3633</guid>

					<description><![CDATA[昨年から Azure を使うようになりました。 ある分野の知識を体系的に学んで身につけるには、資格取得へ向けて勉強するのが良いというのを身を以て知っているので、とりあえず基礎的な AZ-900 を受験してきました。 Mi [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>昨年から Azure を使うようになりました。</p>



<p>ある分野の知識を体系的に学んで身につけるには、資格取得へ向けて勉強するのが良いというのを身を以て知っているので、とりあえず基礎的な AZ-900 を受験してきました。</p>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp/credentials/certifications/azure-fundamentals/?practice-assessment-type=certification" title="Microsoft 認定: Azure Fundamentals - Certifications" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Fcredentials%2Fcertifications%2Fazure-fundamentals%2F%3Fpractice-assessment-type%3Dcertification?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Microsoft 認定: Azure Fundamentals - Certifications</div><div class="blogcard-snippet external-blogcard-snippet">クラウドの概念、Azure のコア サービス、および Azure の管理とガバナンスの機能とツールに関する基本的な知識を示します。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp/credentials/certifications/azure-fundamentals/?practice-assessment-type=certification" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>難易度的には基礎レベルなので、おそらく AWS Certified Cloud Practitioner と同程度と思っています。</p>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-4" checked><label class="toc-title" for="toc-checkbox-4">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">どのような勉強をしたか</a><ol><li><a href="#toc2" tabindex="0">公式</a><ol><li><a href="#toc3" tabindex="0">Microsoft Learn</a></li><li><a href="#toc4" tabindex="0">AWS プロフェッショナル向け Azure</a></li></ol></li><li><a href="#toc5" tabindex="0">テキスト</a><ol><li><a href="#toc6" tabindex="0">全体像と用語がよくわかる! Microsoft Azure入門ガイド</a></li></ol></li></ol></li><li><a href="#toc7" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">どのような勉強をしたか</span></h2>



<p>いつものように書籍を初手で購入したのですが、Microsoft に関連するものは公式の資料やトレーニング用コンテンツが豊富なので、それだけでも良かった気がします。</p>



<h3 class="wp-block-heading"><span id="toc2">公式</span></h3>



<h4 class="wp-block-heading"><span id="toc3">Microsoft Learn</span></h4>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp" title="Microsoft Learn: キャリアの扉を開くスキルを身につける" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Flearn.microsoft.com%2Fja-jp?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Microsoft Learn: キャリアの扉を開くスキルを身につける</div><div class="blogcard-snippet external-blogcard-snippet">ドキュメントやトレーニングによる技術スキルを獲得し、資格を取得し、コミュニティとつながる</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>各認定試験ごとにコースが用意されているようで、今回は AZ-900 受験に向けたコースを受講しました。もちろん無料です。</p>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp/training/courses/az-900t00" title="AZ-900T00-A コース: クラウド インフラストラクチャの概要 - Training" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Ftraining%2Fcourses%2Faz-900t00?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">AZ-900T00-A コース: クラウド インフラストラクチャの概要 - Training</div><div class="blogcard-snippet external-blogcard-snippet">AZ-900T00-A コース: クラウド インフラストラクチャの概要</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp/training/courses/az-900t00" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>コースではサンドボックス内でのハンズオンが用意されています。手を動かしながら覚えられるのは地味に嬉しいですね。</p>



<h4 class="wp-block-heading"><span id="toc4">AWS プロフェッショナル向け Azure</span></h4>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp/azure/architecture/aws-professional" title="AWS プロフェッショナルのための Azure - Azure Architecture Center" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Fazure%2Farchitecture%2Faws-professional?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">AWS プロフェッショナルのための Azure - Azure Architecture Center</div><div class="blogcard-snippet external-blogcard-snippet">Microsoft Azure プラットフォーム、アカウント、サービスの基本について説明します。 AWS プラットフォームと Azure プラットフォームの主な類似点と相違点について説明します。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp/azure/architecture/aws-professional" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>既に AWS を利用している人向けの資料です。これはかなり利用しました。よく知らない Azure のサービス名が出てきたら、まずはこのページを開くぐらいのことはやっていました。</p>



<h3 class="wp-block-heading"><span id="toc5">テキスト</span></h3>



<h4 class="wp-block-heading"><span id="toc6">全体像と用語がよくわかる! Microsoft Azure入門ガイド</span></h4>



<figure class="wp-block-embed aligncenter is-type-rich is-provider-amazon wp-block-embed-amazon"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="全体像と用語がよくわかる! Microsoft Azure入門ガイド" type="text/html" width="1320" height="550" frameborder="0" allowfullscreen style="max-width:100%" src="https://read.amazon.com.au/kp/card?preview=inline&#038;linkCode=kpd&#038;ref_=k4w_oembed_TK8nqcviMkeMiG&#038;asin=4863543689&#038;tag=kpembed-20"></iframe>
</div></figure>



<p>Azure についての知識が0からのスタートだったので、全体を薄く解説している本を用意しようと思っていました。これと「AWS プロフェッショナル向け Azure」を行き来しながら読むと良いと思います。</p>



<h2 class="wp-block-heading"><span id="toc7">まとめ</span></h2>



<p>今まで受験した AWS 認定と比較してもかなり易しかったと思います。クラウドの基礎についての理解と Azure のメインのサービスを触ったことがあれば比較的簡単に合格できそうです。勉強時間はトータルで10時間程度だったと思います。</p>



<p>公式のコンテンツは AWS よりも日本語訳が進んでいるようですが、訳し方にムラがあるように思えます。「Azure Fundamentals」と「Azure の基礎」はどちらかに統一してもらいたかった。。</p>



<p>次も何か受けてみようと思います。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【Azure】Microsoft Entra IDで認可してBlob Storageを操作してみた</title>
		<link>https://wptech.kiichiro.work/14rqfd1ec6/</link>
		
		<dc:creator><![CDATA[むらおか]]></dc:creator>
		<pubDate>Wed, 15 Jan 2025 16:39:45 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[Remix]]></category>
		<guid isPermaLink="false">https://wptech.kiichiro.work/?p=3530</guid>

					<description><![CDATA[Azure Functions などのコンピュートリソースを用意しないで、直接 Blob Storage にファイルをアップロードする方法は無いものか、と考えていたのですが、Microsoft Entra ID で認可で [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Azure Functions などのコンピュートリソースを用意しないで、直接 Blob Storage にファイルをアップロードする方法は無いものか、と考えていたのですが、Microsoft Entra ID で認可できればいいみたいでした。</p>



<p>別解として SAS トークンを利用した認可もありますが、どうやら Entra ID が推奨みたいです。</p>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-javascript-get-started?tabs=typescript%2Cazure-ad#authorize-access-and-connect-to-blob-storage" title="Azure Blob Storage と JavaScript または TypeScript の概要 - Azure Storage" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Fazure%2Fstorage%2Fblobs%2Fstorage-blob-javascript-get-started%3Ftabs%3Dtypescript%252Cazure-ad%23authorize-access-and-connect-to-blob-storage?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Azure Blob Storage と JavaScript または TypeScript の概要 - Azure Storage</div><div class="blogcard-snippet external-blogcard-snippet">Azure Blob Storage で動作する JavaScript または TypeScript アプリケーションの開発を開始します。 この記事では、プロジェクトを設定し、Azure Blob Storage エンドポイントへのアクセス...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-javascript-get-started?tabs=typescript%2Cazure-ad#authorize-access-and-connect-to-blob-storage" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>というわけで、今回は Microsoft Entra ID で認可して Blob Storage にファイルをアップロードするところまでやってみます。</p>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box information-box">
<p>本記事紹介している方法は、Microsoft Entra ID やストレージアカウントの RBAC の設定が甘いと思われます。本番環境で利用する場合は十分なレビューが必要です。</p>
</div>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-6" checked><label class="toc-title" for="toc-checkbox-6">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">構成</a></li><li><a href="#toc2" tabindex="0">Microsoft Entra 管理センター</a></li><li><a href="#toc3" tabindex="0">ストレージアカウント</a><ol><li><a href="#toc4" tabindex="0">Remix アプリ</a><ol><li><a href="#toc5" tabindex="0">ライブラリ</a></li><li><a href="#toc6" tabindex="0">環境変数</a></li><li><a href="#toc7" tabindex="0">認証・認可</a></li></ol></li></ol></li><li><a href="#toc8" tabindex="0">動作確認</a></li><li><a href="#toc9" tabindex="0">おわりに</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">構成</span></h2>



<p>Microsoft Entra ID での認証自体は Remix で作った Web アプリを経由させ、Blob Storage へのアップロードはブラウザから直接行うようにします。登場人物をまとめた図は以下です。</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="402" height="452" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/blob-upload.png" alt="ブラウザからMicrosoft Entra IDで認証してBlob Storageにファイルをアップロードするまでの構成図" class="wp-image-3540" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/blob-upload.png 402w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/blob-upload-267x300.png 267w" sizes="(max-width: 402px) 100vw, 402px" /></figure>



<h2 class="wp-block-heading"><span id="toc2">Microsoft Entra 管理センター</span></h2>



<p>Microsoft Entra 管理センターにて、アプリの登録を行います。アプリの登録ではアプリを一意に示す ID とアプリ自体の認証情報を作成します。</p>



<p>手順は以下を参考に。</p>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp/entra/identity-platform/quickstart-web-app-nodejs-sign-in" title="クイック スタート - サンプル Web アプリでユーザーをサインインする - Microsoft identity platform" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Fentra%2Fidentity-platform%2Fquickstart-web-app-nodejs-sign-in?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">クイック スタート - サンプル Web アプリでユーザーをサインインする - Microsoft identity platform</div><div class="blogcard-snippet external-blogcard-snippet">従業員テナントの従業員または外部テナントの顧客をサインインさせるサンプル Web アプリを構成する方法を示す Web アプリのクイック スタート</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp/entra/identity-platform/quickstart-web-app-nodejs-sign-in" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>アプリの登録が完了すると、概要ペインからクライアント ID とテナント ID を取得できます。</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="302" data-id="3552" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/93bccbc237574d85974089b4572968f8-1024x302.png" alt="クライアントIDとテナントID" class="wp-image-3552" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/93bccbc237574d85974089b4572968f8-1024x302.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/93bccbc237574d85974089b4572968f8-300x88.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/93bccbc237574d85974089b4572968f8-768x227.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/93bccbc237574d85974089b4572968f8-1536x453.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/93bccbc237574d85974089b4572968f8-2048x604.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p>今回は Web アプリ (機密クライアント) を選択したので、クライアントシークレットを生成します。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="209" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/d9b8ab378c3c7b947e88bb30c75b8b13-1024x209.png" alt="" class="wp-image-3557" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/d9b8ab378c3c7b947e88bb30c75b8b13-1024x209.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/d9b8ab378c3c7b947e88bb30c75b8b13-300x61.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/d9b8ab378c3c7b947e88bb30c75b8b13-768x157.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/d9b8ab378c3c7b947e88bb30c75b8b13-1536x314.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/d9b8ab378c3c7b947e88bb30c75b8b13-2048x418.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>




<a rel="noopener" href="https://learn.microsoft.com/ja-jp/entra/identity-platform/msal-client-applications" title="パブリックおよび機密のクライアント アプリ (MSAL) - Microsoft identity platform" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Fentra%2Fidentity-platform%2Fmsal-client-applications?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">パブリックおよび機密のクライアント アプリ (MSAL) - Microsoft identity platform</div><div class="blogcard-snippet external-blogcard-snippet">Microsoft Authentication Library (MSAL) でのパブリック クライアント アプリケーションと機密クライアント アプリケーションについて説明します。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://learn.microsoft.com/ja-jp/entra/identity-platform/msal-client-applications" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">learn.microsoft.com</div></div></div></div></a>



<p>ログイン正常完了時にトークンを送る先をリダイレクト URI として追加します。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="398" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/cfdf6cc48710ac1722fe7cf50ae401fe-1024x398.png" alt="" class="wp-image-3553" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/cfdf6cc48710ac1722fe7cf50ae401fe-1024x398.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/cfdf6cc48710ac1722fe7cf50ae401fe-300x117.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/cfdf6cc48710ac1722fe7cf50ae401fe-768x299.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/cfdf6cc48710ac1722fe7cf50ae401fe-1536x598.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/cfdf6cc48710ac1722fe7cf50ae401fe-2048x797.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading"><span id="toc3">ストレージアカウント</span></h2>



<p>Microsoft Entra ID で認証されたユーザーに Blob Storage の操作を許可します。これを実現するには、ロールベースのアクセス制御である Azure RBAC を利用します。</p>



<p>まずは Azure portal から任意のストレージアカウントとコンテナーを作成します。作成できたら、アクセス制御 (IAM) ペインから 追加タブ > ロールの割り当ての追加 を選択します。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="461" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/696c2c36a841fe44d5a74a6bdf46fff7-1024x461.png" alt="ロールの割り当ての追加" class="wp-image-3571" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/696c2c36a841fe44d5a74a6bdf46fff7-1024x461.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/696c2c36a841fe44d5a74a6bdf46fff7-300x135.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/696c2c36a841fe44d5a74a6bdf46fff7-768x346.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/696c2c36a841fe44d5a74a6bdf46fff7-1536x692.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/696c2c36a841fe44d5a74a6bdf46fff7-2048x923.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>データ共同作業者を選択して次へを選択します。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="430" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/331b7821a9217c0959e15fe949e8a734-1024x430.png" alt="" class="wp-image-3573" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/331b7821a9217c0959e15fe949e8a734-1024x430.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/331b7821a9217c0959e15fe949e8a734-300x126.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/331b7821a9217c0959e15fe949e8a734-768x323.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/331b7821a9217c0959e15fe949e8a734-1536x645.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/331b7821a9217c0959e15fe949e8a734-2048x860.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>許可するユーザーを追加してレビューと割り当てを選択します。</p>



<h3 class="wp-block-heading"><span id="toc4">Remix アプリ</span></h3>



<p>Remix で作ったものは GitHub にアップしてます。</p>




<a rel="noopener" href="https://github.com/ShotaroMuraoka/azure-entra-auth-blob-storage" title="GitHub - ShotaroMuraoka/azure-entra-auth-blob-storage: Azure Blob Storage へのアクセスを Microsoft Entra ID で認可するアプリ" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Fgithub.com%2FShotaroMuraoka%2Fazure-entra-auth-blob-storage?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">GitHub - ShotaroMuraoka/azure-entra-auth-blob-storage: Azure Blob Storage へのアクセスを Microsoft Entra ID で認可するアプリ</div><div class="blogcard-snippet external-blogcard-snippet">Azure Blob Storage へのアクセスを Microsoft Entra ID で認可するアプリ - ShotaroMuraoka/azure-entra-auth-blob-storage</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://github.com/ShotaroMuraoka/azure-entra-auth-blob-storage" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">github.com</div></div></div></div></a>



<p>以降はポイントのみを説明していきます。</p>



<h4 class="wp-block-heading"><span id="toc5">ライブラリ</span></h4>



<p>Remix で Microsoft Entra ID を使った認証と Blob Storage の操作を行うのに以下のライブラリを利用しています。</p>



<ul class="wp-block-list">
<li>remix-auth: 3.7.0</li>



<li>remix-auth-microsoft: 2.0.1</li>



<li>remix-auth-oauth2: 1.11.0</li>



<li>@azure-storage-blob: 12.26.0</li>
</ul>



<h4 class="wp-block-heading"><span id="toc6">環境変数</span></h4>



<p><code>.env</code> を作成し、取得した ID とクライアントシークレット、ストレージアカウント名などを記載します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain" data-file=".env"><code>ENTRA_CLIENT_ID={クライアントID}
ENTRA_CLIENT_SECRET={クライアントシークレット}
ENTRA_REDIRECT_URI=http://localhost:5173/auth/microsoft/callback
ENTRA_TENANT_ID={テナントID}
AZURE_STORAGE_ACCCOUNT={ストレージアカウント名}
AZURE_BLOB_CONTAINER={コンテナー名}</code></pre></div>



<h4 class="wp-block-heading"><span id="toc7">認証・認可</span></h4>



<p><code>remix-auth-microsoft</code> では MicrosoftStrategy が用意されているので、それを利用した Authenticator を作っています。</p>



<p>ここでは、scope に Azure Storage のアクセストークンの要求を追加しています。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="app/services/auth.server.ts" data-lang="TypeScript" data-line="11"><code>let microsoftStrategy = new MicrosoftStrategy(
  {
    clientId: process.env.ENTRA_CLIENT_ID || &quot;&quot;,
    clientSecret: process.env.ENTRA_CLIENT_SECRET || &quot;&quot;,
    redirectUri: process.env.ENTRA_REDIRECT_URI || &quot;&quot;,
    tenantId: process.env.ENTRA_TENANT_ID || &quot;&quot;,
    scope: [
      &quot;openid&quot;,
      &quot;email&quot;,
      &quot;profile&quot;,
      &quot;https://storage.azure.com/user_impersonation&quot;,
    ], // optional
    prompt: &quot;login&quot;, // optional
  },</code></pre></div>



<p>取得したアクセストークンはセッション情報に書き出されるので、loader でフロントエンドに渡しています。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="app/routes/dashboard.tsx" data-lang="TypeScript" data-line="7"><code>export async function loader({ request }: LoaderFunctionArgs) {
  const user = await authenticator.isAuthenticated(request);
  if (!user) {
    throw new Response(&quot;Unauthorized&quot;, { status: 403 });
  }

  const accessToken = user.accessToken;
  const storageAccount = process.env.AZURE_STORAGE_ACCCOUNT;
  const blobContainer = process.env.AZURE_BLOB_CONTAINER
  return { accessToken, storageAccount, blobContainer };
}
</code></pre></div>



<p>アクセストークンは <code>@azure-storage-blob</code> が提供するクライアントの生成に利用しています。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="app/routes/dashboard.tsx" data-lang="TypeScript" data-line="2"><code>const blobServiceClient = createBlobServiceClient(
  accessToken,
  storageAccount,
);

const containerClient = blobServiceClient.getContainerClient(blobContainer);
const blockBlobClient = containerClient.getBlockBlobClient(file.name);

try {
  const response = await blockBlobClient.uploadBrowserData(file, {
    blobHTTPHeaders: { blobContentType: file.type },
  });
  console.log(&quot;upload succeeded&quot;, response.requestId);
  alert(&quot;ファイルアップロード完了&quot;);
} catch (error) {
  console.error(&quot;upload failed&quot;, error);
  alert(&quot;ファイルアップロード失敗&quot;);
}</code></pre></div>



<h2 class="wp-block-heading"><span id="toc8">動作確認</span></h2>



<p>アプリを起動します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code># npm run dev </code></pre></div>



<p>ブラウザで <code>http://localhost:5173/login</code> にアクセスします。</p>



<figure class="wp-block-image aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="437" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/4ac2c4d89027686851bc700e533bd679-1024x437.png" alt="" class="wp-image-3610" style="width:499px;height:auto" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/4ac2c4d89027686851bc700e533bd679-1024x437.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/4ac2c4d89027686851bc700e533bd679-300x128.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/4ac2c4d89027686851bc700e533bd679-768x327.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/4ac2c4d89027686851bc700e533bd679.png 1032w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>ログインボタンを押下すると、Microsoft のサインイン画面にリダイレクトされます。</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="976" height="742" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/a210c4a89a86a2f1249080781e3bd2c1.png" alt="" class="wp-image-3612" style="width:422px;height:auto" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/a210c4a89a86a2f1249080781e3bd2c1.png 976w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/a210c4a89a86a2f1249080781e3bd2c1-300x228.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/a210c4a89a86a2f1249080781e3bd2c1-768x584.png 768w" sizes="(max-width: 976px) 100vw, 976px" /></figure>



<p>ストレージアカウントで許可したユーザーの認証情報を入力してログインに成功すると、ダッシュボード画面にリダイレクトします。初回ログイン時にのみ、Azure Storage へのアクセス許可を聞かれます。</p>



<figure class="wp-block-image aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="641" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/7963341bc5a5350c17c2cf5915d87052-1024x641.png" alt="" class="wp-image-3614" style="width:486px;height:auto" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/7963341bc5a5350c17c2cf5915d87052-1024x641.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/7963341bc5a5350c17c2cf5915d87052-300x188.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/7963341bc5a5350c17c2cf5915d87052-768x481.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/7963341bc5a5350c17c2cf5915d87052.png 1138w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>任意のファイルを選択して Upload ボタンを押下します。ファイルのアップロードが成功するとメッセージが表示されます。</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="1012" height="510" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/c52d0320f5e473f648f6bec45c03dcd3.png" alt="" class="wp-image-3617" style="width:484px;height:auto" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/c52d0320f5e473f648f6bec45c03dcd3.png 1012w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/c52d0320f5e473f648f6bec45c03dcd3-300x151.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/c52d0320f5e473f648f6bec45c03dcd3-768x387.png 768w" sizes="(max-width: 1012px) 100vw, 1012px" /></figure>



<p>Blob コンテナーを見てみると、ファイルがアップロードされていることが確認できます。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="353" src="https://wptech.kiichiro.work/wp-content/uploads/2025/01/68f3872b98c096bfebd9e36277eccf5c-1024x353.png" alt="" class="wp-image-3619" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/01/68f3872b98c096bfebd9e36277eccf5c-1024x353.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/68f3872b98c096bfebd9e36277eccf5c-300x103.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/68f3872b98c096bfebd9e36277eccf5c-768x264.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/68f3872b98c096bfebd9e36277eccf5c-1536x529.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/01/68f3872b98c096bfebd9e36277eccf5c.png 1766w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading"><span id="toc9">おわりに</span></h2>



<p>普段、Azure や Entra ID を利用する機会が無いので、難易度が高かったです。次は SAS トークンを試してみようと思います。</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
