Ayumu Inaba
Cloud Solution Architect
Microsoft Japan
Azure AD Auth
for Azure Applications
1
Agenda
Azure AD ユーザー認証の挙動(Exchange Online)
Azure Web App のユーザー認証
SQL Database のユーザー認証
SQL Database のアプリ認証
Azure Web App へのユーザー認証情報の委任
OAuth2 プロトコルとの対比
2
認証のレイヤー
3
IaaS
OS / Middleware
Application / Data
PaaS
Application / Data
SaaS
想定アーキテクチャ
主に Azure Web App, SQL Database に対する Azure
AD 認証を取り扱う
4
? ? ?
5
Office 365 の場合
6
POST /owa/ HTTP/1.1
Host: outlook.office365.com
code: AQABAAIAAABeAFzDwllzTY…
id_token: eyJ0eXAiOiJKV1QiLCJhbGciO…
③ ログイン画面
HTTP/1.1 302 Found
Location: https://login.onmicrosoft.com/common/oauth2/authorize
?client_id=00000002-0000-0ff1-ce00-000000000000
&redirect_uri=https://outlook.office365.com/owa/
&response_type=code+id_token
&scope=openid
&etc…
⑤ メールボックスが
見られる
https://jwt.ms
https://outlook.office365.com/owa
Office 365 の場合
7
https://portal.azure.com https://myapps.microsoft.com
8
Web アプリで Azure AD 認証を構成するには
Web アプリケーション
適切なトークンを持つリクエストに応じたアクセス制御を行う
適切なトークン情報を持たない場合 Azure AD の認可エンドポイントへ誘導する
その際に必要とするアプリケーション情報を指定する
トークンを返却してもらうための URI を指定する
Azure Active Directory
アクセスしているユーザーの正当性を確認する
登録されたアプリに対してユーザーの同意を取得する
トークンを発行してアプリケーションに返却する
9
Azure Web App ユーザー認証の動作イメージ
Web App は Azure AD を信頼し、認証を委託する ”クライ
アント”アプリケーション
ユーザーは AAD で認証を受け、 Web App が自身の情報にアクセスすることに同意する
Web App は指定のディレクトリで発行された認可コードを持つリクエストを処理する
10
ApplicationEasy
Auth
Azure Web App ユーザー認証の構成
WebApp の認証設定:EasyAuth を使用すると構成が容易
簡易モードであれば AAD へのアプリ登録、設定情報の交換、トークンチェック、トークンがな
い場合のリダイレクト、ユーザーアプリへのトークンの伝搬などを自動でやってくれる
Azure ポータルで認証に使用している AAD テナントでユーザー認証する場合、かつ、
Azure ポータルのログインユーザーにアプリ登録権限がある場合に限る
11https://docs.microsoft.com/ja-jp/azure/app-service/configure-authentication-provider-aad
AAD 認証のメリットと留意事項
Azure AD 管理者
Office 365 等と同様に 3rd Party 製や自社独自
のアプリを管理できる
全てのアプリで同じ ID 運用・同等の認証強度を提
供することができる
留意事項
不適切なアプリケーションに対して認可コードやトー
クンを払い出すのは極めて危険
Azure AD に登録されたアプリケーションが適切なも
ののみであるように管理すること
アプリケーション開発者
独自のセキュリティ設計・実装・運用をすることなく、ア
プリケーションの開発に専念することができる
標準的な認証・認可のプロトコルを採用することで、外
部との相互運用がしやすい
留意事項
認証後に取得した認可コードやトークンが悪用されな
いように適切な実装を心がける
アプリに対して過大なスコープや権限を持たせないよ
うに設計すること
12
ユーザー割り当て
アプリケーションへのアクセスをディレクトリ内の特定のユー
ザーに限定したい場合は「ユーザーの割り当て」を行う
EasyAuth を有効にしただけでは、当該ディレクトリに登録されたユーザーであると認証され
ているだけ(=組織のユーザーであれば全員使用できる)
13https://docs.microsoft.com/ja-jp/azure/active-directory/manage-apps/methods-for-assigning-users-and-groups
このアプリを使って良いユーザー
やグループを登録
補足 : IaaS やオンプレで実装する場合
EasyAuth がやってくれていた内容をアプリケーションの一
部として実装することになる
ミドルウェアや SDK が AAD 認証に対応している場合には、それを使用すると良い
14
OS
Web サーバー
ミドルウェア
アプリケーション
認証ずみリクエストのみを
アプリケーションに受け渡す
補足 : Azure AD Application Proxy
オンプレミスでや VM 上で動作する既存の Web サーバーに
対する AAD 認証付きのリバースプロキシ
https://docs.microsoft.com/ja-jp/azure/active-directory/manage-
apps/application-proxy
Azure AD Premium P1 / P2 のライセンスが必要
15
コネクタからの
送信接続でトン
ネルを構築
Windows 統合認証
への変換も可能
16
SQL Database の AAD 認証の構成と動作
17
サブスクリプション
Azure を操作できる
管理者・開発者
データベース管理者
sqladmin
データベース利用者
sqluser
アプリケーション
sqladmin を AD 管理者に設定
sqluser やアプリを
データベースロールに追加
Azure Data Studio 等の GUI で
開発・保守・運用作業を行う
アクセストークンを用いて
データベースに接続
信頼
Azure Active Directory
構成
利用
ユーザーやアプリを登録
Azure Portal や CLI で操作
SSMS や Azure Data Sudio、
Client SDK などで操作
SQL Database に対する
アクセストークンが必要
Azure AD 認証の有効化
SQL Database の Active Directory 管理者を指定する
名前がややこしいが、 AD を管理する人ではなく、 SQL DB にアクセスする AAD ユー
ザーやアプリケーションを管理する人
18
SQL DB の AD 管理者によるアクセス
AD 管理者は自身の AAD 認証情報を使用して SQL
Database にアクセスできる
SQL Server Management Studio や Azure Data Studio など、 Azure AD 認証に
対応したクライアントツールを使用
19
AAD ユーザーの登録
AD 管理者は他のユーザーを SQL DB にユーザー登録、
データベースロールを割り当てることができる
この操作は SQL 認証で接続した管理者では実行できない
アクセスさせたいユーザーが多数の場合は AAD グループで登録すると良い
20
-- AAD ユーザーの登録
CREATE USER [sqluser1@tenantname.onmicrosoft.com] FROM EXTERNAL PROVIDER;
ALTER ROLE db_reader ADD MEMBER [sqluser1@tenantname.onmicrosoft.com];
-- AAD グループの登録
CREATE USER [sqlusers-group] FROM EXTERNAL PROVIDER;
ALTER ROLE db_owner ADD MEMBER [sqlusers-group];
T-SQL
AAD ユーザーによるアクセス
SQL DB に登録された AAD ユーザーは AD 管理者と同
様に自身の AAD 認証情報を使用してアクセスできる
複数のユーザーが 1 つの ID/Password を使い回すことなく、日常的に使用している認証
情報を使用してアクセスすることができる(多要素認証にも対応可能)
21
補足 : AAD ユーザーによるアクセス
アプリケーションコードで AAD ユーザーの認証情報を使用
してアクセスすることも可能
接続文字列で Authentication=Active Directory Password; を指定
ユーザーのパスワード変更や多要素認証に対応できなくなるため、通常は行わない
22
using Microsoft.Data.SqlClient;
public SqlConnection CreateAadUserConnection()
{
var constr = "Server=tcp:servername.database.windows.net,1433;Initial Catalog=dbname;"
+ "Authentication=Active Directory Password; "
+ "User ID=sqluser@tenantname.onmicrosoft.com;Password=P@ssw0rd!";
return new SqlConnection(constr);
}
C#
Microsoft.Data.SqlClient パッケージ(https://www.nuget.org/packages/Microsoft.Data.SqlClient/)を使用
実際には環境変数等の
外部に切り出すこと
23
AAD アプリによるアクセス
ユーザーが介在しない場合は AAD にアプリケーションを登
録して SQL DB にアクセスする
常駐型デーモンアプリ、バッチアプリ、 Web アプリなど
接続文字列に埋め込まれた情報ではなく AAD 発行のアクセストークンを使用する
24
AAD アプリによるアクセス
アクセストークンを取得する方法は以下の4パターン
① 新規に作成したサービスプリンシパルのキー(または証明書)を使用する
② AAD 認証設定時に生成されたサービスプリンシパルのキーを使用する
③ システム割り当てマネージド ID を使用する
④ ユーザー割り当てマネージド ID を使用する
トークンを取得すれば SqlConnection の作成は同じ
25
using Microsoft.Data.SqlClient;
private static SqlConnection GetAadAppTokenConnection()
{
var token = GetAccessToken(); // トークンの取得方法によって実装を変える
var constr = @"Server=tcp:sqlsvrName.database.windows.net,1433;Initial Catalog=dbName;";
var connection = new SqlConnection(constr);
connection.AccessToken = token;
return connection;
}
C#
実際には環境変数等の
外部に切り出すこと
AAD アプリによるアクセス
前述の ①〜④ で作成されるサービスプリンシパルに対して
SQL Database に対するアクセス権を付与する
A) データベースユーザーおよびロールに登録する
B) すでにデータベースユーザーおよびロールに登録された AAD グループに追加する
26
-- A) DB 管理者による AAD アプリの登録
CREATE USER [sqlapp_sp] FROM EXTERNAL PROVIDER;
ALTER ROLE db_reader ADD MEMBER [sqlapp_sp];
T-SQL
① 新規サービスプリンシパルによるアクセス
Azure AD にアプリケーション登録権限を持った管理者が下
記の情報を準備
アプリケーション名
アプリケーション ID
ディレクトリ ID
クライアント シークレット
上記の情報をもとに、前述のように
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
27
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-create-service-principal-portal
① 新規サービスプリンシパルによるアクセス
アプリケーションはキーや証明書を使用して SQL Database
に対するアクセストークンを取得することができる
Azure AD にアクセス可能な環境であれば、必ずしも Azure 上で動作させる必要はなく、
オンプレミスや他社クラウドでも良い
28
using Microsoft.Identity.Client;
private static string GetAccessTokenWithServicePrincipal()
{
var directoryid = "guid-of-your-azuread-directory-id";
var applicatonid = "guid-of-your-application-id";
var clientkey = "key-secret-generated";
var scopes = new[] { "https://database.windows.net/.default" };
var app = ConfidentialClientApplicationBuilder
.Create(applicationid)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{directoryid}"))
.WithClientSecret(clientkey)
.Build();
var authresult = app.AcquireTokenForClient(scopes).ExecuteAsync().Result;
return authresult.AccessToken;
}
C#
https://www.nuget.org/packages/Microsoft.Identity.Client/
実際には環境変数等の外部に切り出すこと
Azure Web App なら構成情報に記載
② 認証設定のサービスプリンシパルを流用
AAD 認証を設定した Web App は既にAzure AD にアプリ
登録されている
29
Web App と同名のアプリケーションが
登録されているのでこの名前で
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
② 認証設定のサービスプリンシパルを流用
Web App の認証設定画面の情報は環境変数から取得でき
るように設定されている
ASP.NET Core アプリケーションであれば Environment.GetEnvironmantVariable()
や Configuration で取得できる
30
using Microsoft.Identity.Client;
private static string GetAccessTokenFromAppServiceEasyAuth ()
{
var clientid = _config["WEBSITE_AUTH_CLIENT_ID"];
var secret = _config["WEBSITE_AUTH_CLIENT_SECRET"];
var guidpattern = @"([A-Fa-f0-9]{8})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{12})";
var tenantid = Regex.Match(_config["WEBSITE_AUTH_OPENID_ISSUER"], guidpattern).Groups[0].Value;
var authority = new Uri($"https://login.microsoftonline.com/{tenantid}");
var scopes = new[] { "https://database.windows.net/.default" };
var app = ConfidentialClientApplicationBuilder
.Create(clientid).WithAuthority(authority).WithClientSecret(secret).Build();
var builder = app.AcquireTokenForClient(scopes);
var authResult = await builder.ExecuteAsync();
return authResult.AccessToken;
}
C#
補足:環境変数の一覧
一度 Web App で設定される環境設定値を確認するための
アプリを作ってデプロイしてみると手っ取り早い
認証設定周りの情報は WEBSITE_AUTH_XXXX に
設定されている
31
<div>
<h2>環境変数</h2>
<table class="table">
<thead>
<tr> <th>Key</th> <th>Value</th> </tr>
</thead>
<tbody>
@foreach (string key in Environment.GetEnvironmentVariables().Keys.OfType<string>())
{
<tr>
<td><span>@key</span></td>
<td><span>@(Environment.GetEnvironmentVariable(key))</span></td>
</tr>
}
</tbody>
</table>
</div>
ASP.NET Core
③ システム割当マネージ ID を使用したアクセス
Web App にマネージド ID を割り当てておくと、そこで動作
するアプリがトークンを取得するエンドポイントが用意される
この場合も Web App と同じ名前のサービスプリンシパルが AAD に作成される
32
https://docs.microsoft.com/ja-jp/azure/app-service/overview-managed-identity?tabs=dotnet
Web App と同名のアプリケーションが
登録されているのでこの名前で
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
③ システム割当マネージ ID を使用したアクセス
Web App にデプロイされたアプリは実行環境からマネージ
ド ID を使用してアクセストークンを取得することができる
アクセストークンの取得は Azure AD のトークンエンドポイントではなく、Web App 環境内に
用意されるエンドポイントを使用する
ASP.NET Core の場合は System.Net.Http や Json.NET などを使用する
33
using System.Net.Http;
using Newtonsoft.Json.Linq;
private static async Task<string> GetAccessTokenFromSystemAssignedManagedId()
{
var resourceuri = "https%3A%2F%2Fdatabase.windows.net%2F";
var msiurl = string.Format("{0}?resource={1}&api-version=2017-09-01", _config["MSI_ENDPOINT"], resourceuri);
string token = null;
using (var hc = new HttpClient())
{
hc.DefaultRequestHeaders.Add("Secret", _config["MSI_SECRET"]);
var ret = await hc.GetStringAsync(msiurl);
token = JObject.Parse(ret)["access_token"].ToString();
}
return token;
}
C#
マネージ ID 用のトークンエンドポイント URL が設定され
ている環境変数を使用して下記 URL を組み立てている
http://127.0.0.1:41631/MSI/token/
?resource=http://database.windows.net
&api-version=2017-09-01
③ システム割当マネージ ID を使用したアクセス
マネージド ID を使用してアクセストークンを取得する専用の
ライブラリが提供されている場合はそちらを使うと良い
ASP.NET Core の場合は Microsoft.Azure.Services.AppAuthentication が利用で
きる
34
using Microsoft.Azure.Services.AppAuthentication;
private static async Task<string> GetAccessTokenFromSystemAssignedManagedId()
{
var provider = new AzureServiceTokenProvider();
var token = await provider.GetAccessTokenAsync("https://database.windows.net/");
return token;
}
C#
アクセストークンを取得した
い対象リソースの URI だけ
指定すれば良い
④ ユーザ割当マネージ ID を利用したアクセス
ユーザー割り当てマネージ ID は柔軟な構成が可能
1つのマネージ ID を複数の WebApp や VM に割り当てて共用する
1つの Web App に対して複数のマネージ ID を割り当てアクセス先に応じて使い分けるこ
とができる
35
対象となる Web App に割り当てる
マネージ ID と同名のサービスプリンシ
パルが登録されているのでこの名前で
A) SQL DB のユーザーを作成するか
B) AAD グループに追加しておく
④ ユーザ割当マネージ ID を利用したアクセス
アクセストークンの取得クライアント ID を指定する以外システ
ム割当の場合とほぼ同じ
36
using System.Net.Http;
using Newtonsoft.Json.Linq;
private static async Task<string> GetAccessTokenFromSystemAssignedManagedId()
{
string token = null;
using (var hc = new HttpClient())
{
var resourceuri = "https%3A%2F%2Fdatabase.windows.net%2F";
var msiurl = string.Format("{0}?resource={1}&api-version=2017-09-01&clientid={2}"
, _config["MSI_ENDPOINT"], resourceuri, "guid-of-clientid-for-uamid");
hc.DefaultRequestHeaders.Add("Secret", _config["MSI_SECRET"]);
var ret = await hc.GetStringAsync(msiurl);
token = JObject.Parse(ret)["access_token"].ToString();
}
return token;
}
C#
Tips : AAD ユーザーの確認
SQL Database に登録した AAD ユーザーやグループおよ
びデータベースロールは下記のように確認できる
37
SELECT
DP1.name AS DatabaseRoleName,
isnull (DP2.name, 'No members') AS DatabaseUserName ,
DP2.type_desc as PrincipalType,
DP2.sid
FROM sys.database_role_members AS DRM
RIGHT OUTER JOIN sys.database_principals AS DP1
ON DRM.role_principal_id = DP1.principal_id
LEFT OUTER JOIN sys.database_principals AS DP2
ON DRM.member_principal_id = DP2.principal_id
WHERE DP1.type = 'R'
ORDER BY DP1.name;
T-SQL
Tips:現在の SQL セッションのユーザー
SQL Database に接続できたら現在どのユーザーで接続
しているのかを確認してみると良い
38
using Microsoft.Data.SqlClient;
private static async Task OnGet()
{
var connection = GetAadAppTokenConnection();
try
{
await connection.OpenAsync();
using ( var cmd = connection.CreateCommand() )
{
cmd.CommandText = "select suser_name()";
var dbuser = cmd.ExecuteScalar().ToString();
}
}
finally
{
connection.Close();
}
}
C#
Tips : アプリ名の重複
Web App の以下の操作で ”同名のサービスプリンシパル”
が作成され、SQL DB への登録時に区別がつかない
AAD ユーザー認証を構成する
システム割当マネージ ID を有効にする
39
ユーザー認証(簡易モード)で作成された
サービスプリンシパル
マネージ ID で作成されたサービスプリンシパル
-- A) DB 管理者による AAD アプリの登録
CREATE USER [ainaba-aadauth-web]
FROM EXTERNAL PROVIDER;
T-SQL
Tips : アプリ名の重複
回避策としては以下が考えられる
ユーザー認証では簡易モードを使用しない(アプリ登録時に名前を指定できる)
ユーザー割当マネージド ID を使用する(マネージド ID 作成時に名前を指定できる)
SQL DB にアクセス可能な AAD グループに登録する(Azure ポータルで区別:下記参照)
ユーザー登録時に sid を明示的に指定して名前をずらす(次ページ)
40
オブジェクト ID で
区別がつく
Tips : アプリ名の重複
SQL DB への登録時に SID を使用してアプリケーションを
明示的に指定することができる
41
## アプリケーション ID から SID を生成
PS> $b = [Guid]::Parse("eb49934f-…").ToByteArray()
PS> "0x" + (($b | % {$_.ToString("X2")}) –join "")
0x4F9349EB85BD…
PowerShell
-- sid を指定することで AAD アプリとは別名をつける
CREATE USER [ainaba-aadauth-web-mi2]
with sid = 0x4F9349EB85BD…, type = E;
-- 別名のユーザーをデータベースロールに追加
ALTER ROLE db_owner ADD MEMBER [ainaba-aadauth-web-mi2];
T-SQL
補足: VM でアプリが動作する場合
アプリが Azure VM 上で動作する場合も同様の実装が可能
だがいくつか差異が発生する
AAD ユーザー認証を自動構成してくれる簡易機能は提供されない
> 対応する Web アプリの認証するライブラリを利用して自力で実装する
サービスプリンシパルのキー情報などは環境変数に自動設定されない
> 自力で環境変数に設定するか、構成設定ファイルやレジストリで管理する
マネージ ID によるトークンエンドポイントが異なる
> URL が異なる程度だがコードの流用時に注意
システム割当マネージ ID は VM インスタンスごとに異なるオブジェクトになる
> ユーザー割当マネージ ID や AAD グループによる管理を検討する
詳細は下記の Blog などを参照
https://ayuina.github.io/ainaba-csa-blog/sqldb-aad-authentication/
42
43
ユーザー認証の委任(Delegate)
アプリケーションが DB アクセスする際に、アクセス元のユー
ザーのふりをしてアクセスすることも出来る
Azure AD に登録された Web アプリに対して SQL DB アクセスを委任する
SQL DB も Azure AD にアプリとして登録されている
(022907d3-0f1b-48f7-badc-1ba6abab6d66)
44
Web App によるアクセストークンの自動取得
ユーザー認証が有効になっている Web App であれば、
SQL DB のアクセストークンも取得を任せることができる
Web App の認証時に SQL DB へのアクセストークンも発行するように構成
Microsoft.Web/sites/appName/config/authsettings/properties/additionalLoginParams
45
// ポータルでは設定できないので Resource Explorer 等で
// 認証設定のオプションを指定
additionalLoginParams : [
"response_type=code id_token",
"resource=https://database.windows.net"
]
ARM
Web App によるアクセストークンの自動取得
Web App が取得したアクセストークンをそのまま SQL
Connection に設定するだけで良い
EasyAuth によって X-MS-TOKEN-AAD-ACCESS-TOKEN ヘッダーに設定される
46
private static async Task<string> GetAccessTokenAsUser()
{
return Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"];
}
C#
Easy
Auth App
X-MS-TOKEN-AAD-
ACCESS-TOKEN SQL
Connection
アプリ側でアクセストークンを取得する
2つ以上のリソースアクセスの委任が必要な場合は、リフレッ
シュトークンを使用してアプリから取得する
"X-MS-TOKEN-AAD-REFRESH-TOKEN" HTTP ヘッダーを使用
47
Easy
Auth App
X-MS-TOKEN-AAD-
REFRESH-TOKEN SQL
Connection
アプリ側でアクセストークンを取得する
こちらの手法であれば任意のタイミングに任意のリソースに対
してアクセストークンを取得できる
48
private static async Task<string> GetAccessTokenAsUser()
{
var clientid = _config["WEBSITE_AUTH_CLIENT_ID"];
var secret = _config["WEBSITE_AUTH_CLIENT_SECRET"];
var guidpattern = @"([A-Fa-f0-9]{8})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{12})";
var tenantid = Regex.Match(_config["WEBSITE_AUTH_OPENID_ISSUER"], guidpattern).Groups[0].Value;
var authority = new Uri($"https://login.microsoftonline.com/{tenantid}");
var scopes = new[] { "https://database.windows.net/.default" };
var app = ConfidentialClientApplicationBuilder
.Create(clientid).WithAuthority(authority).WithClientSecret(secret).Build() as IByRefreshToken;
var authcode = Request.Headers["X-MS-TOKEN-AAD-REFRESH-TOKEN"][0];
var builder = app.AcquireTokenByRefreshToken(scopes, authcode);
var result = await builder.ExecuteAsync();
return result.AccessToken;
}
ARM
補足:HTTP ヘッダー情報の一覧
一度 Web App で動作するアプリが受け取るリクエストヘッ
ダーを確認するアプリを作ってデプロイしてみると早い
Web App にアクセスしているユーザー情報は
X-MS-CLIENT-PRINCIPAL-XXXX で
AAD から渡されるトークン関係の情報は
X-MS-TOKEN-AAD-XXXX で取得できる
49
<div>
<h2>HTTP リクエストヘッダー</h2>
<table class="table">
<thead>
<tr> <th>Key</th> <th>Value</th> </tr>
</thead>
<tbody>
@foreach (string key in string key in Request.Headers.Keys.OfType<string>())
{
<tr>
<td><span>@key</span></td>
<td><span>@(Request.Headers[key])</span></td>
</tr>
}
</tbody>
</table>
</div>
ASP.NET Core
50
Web App のサインイン
51
① サインインしていないリクエストを Azure AD にリダイレクト
https://login.microsoftonline.com/{tenant}/oauth2/authorize
?response_type=code+id_token
&redirect_uri=https://{appName}.azurewebsites.net/.auth/login/aad/callback
&client_id={guid-of-application-registered}
&scope=openid+profile+email
&response_mode=form_post
&nonce=xxxxxxx
&state=xxxxxxx
OAuth 2.0 承認エンドポイント を使用した Open ID Connect およ
び
② サインイン(およびユーザーの同意)
登録されたアプリ(client_id, redirect_uri)である
ことを確認し、ユーザーのサインイン操作に応じて、認
可コード(code)と ID トークン(id_token)を返却
③ コールバック
Web App の指定されたコールバック
URL に認可コード(code)と ID トークン
(id_token)をポスト(form_post)
④ 認証クッキーの発行
提示された認可コード(code)と ID トークン
(id_token)を確認し、認証状態を維持するための
クッキー AppServiceAuthSession を発行
⑤ アプリケーションの利用
以降のリクエストに認証クッキーを
付与することで認証済みユーザーと
してアプリケーションを利用
⑥ アプリケーションの動作
EasyAuth がリクエストヘッダーに
設定した各種トークン等を活用して
API アクセスなどを行う
SQL Database への委任アクセス
52
⑦ ユーザーの認可コードを使用してアクセストークンを取得
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id={guid-of-application-registered}
&scope=https://database.windows.net/.default
&code={authorization_code}
&redirect_uri=https://{appName}.azurewebsites.net/.auth/login/aad/c
allback
&grant_type=authorization_code
&client_secret={secretKeyOfApplication}
OAuth 2.0 トークンエンドポイント を使用した Authorization
Code Flow
⑧ アクセストークンを提示
SqlConnection オブジェクトの
AccessToken プロパティにセット
⑨ アクセス制御
SQL DB の登録ユーザーおよび
データベースロールを確認
サインイン時にアプリが認可
コードを用いてアクセストークン
を取得することを委任
SQL Database へのアプリケーション アクセス
53
① アプリケーションとしてアクセストークンを取得
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id={guid-of-application-registered}
&scope=https://database.windows.net/.default
&client_secret={secretKeyOfApplication}
&grant_type=client_credentials
OAuth 2.0 トークンエンドポイント を使用した
Client Credentials Grant Flow
② アクセストークンを提示
SqlConnection オブジェクトの
AccessToken プロパティにセット
③ アクセス制御
SQL DB の登録ユーザーおよび
データベースロールを確認
ユーザーは関与しない
リファレンス
Open ID Connect
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-
protocols-oidc
Authorization Code Flow
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-
oauth2-auth-code-flow
Client Credentials Flow
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-
oauth2-client-creds-grant-flow
54
MICROSOFT CONFIDENTIAL
本資料は情報提供のみを⽬的としており、本資料に記載されている情報は、本資料作成時点でのマイクロソフトの⾒解を⽰し
たものです。状況等の変化により、内容は変更される場合があります。本資料に表記されている内容(提⽰されている条件等
を含みます)は、貴社との有効な契約を通じて決定されます。それまでは、正式に確定するものではありません。従って、本資
料の記載内容とは異なる場合があります。また、本資料に記載されている価格はいずれも、別段の表記がない限り、参考価
格となります。貴社の最終的な購⼊価格は、貴社のリセラー様により決定されます。マイクロソフトは、本資料の情報に対して
明⽰的、黙⽰的または法的な、いかなる保証も⾏いません。
© 2019 Microsoft Corporation. All rights reserved.
MICROSOFT CONFIDENTIAL
本資料は情報提供のみを⽬的としており、本資料に記載されている情報は、本資料作成時点でのマイクロソフトの⾒解を⽰し
たものです。状況等の変化により、内容は変更される場合があります。本資料に表記されている内容(提⽰されている条件等
を含みます)は、貴社との有効な契約を通じて決定されます。それまでは、正式に確定するものではありません。従って、本資
料の記載内容とは異なる場合があります。また、本資料に記載されている価格はいずれも、別段の表記がない限り、参考価
格となります。貴社の最終的な購⼊価格は、貴社のリセラー様により決定されます。マイクロソフトは、本資料の情報に対して
明⽰的、黙⽰的または法的な、いかなる保証も⾏いません。
© 2019 Microsoft Corporation. All rights reserved.

AAD authentication for azure app v0.1.20.0317

  • 1.
    Ayumu Inaba Cloud SolutionArchitect Microsoft Japan Azure AD Auth for Azure Applications 1
  • 2.
    Agenda Azure AD ユーザー認証の挙動(ExchangeOnline) Azure Web App のユーザー認証 SQL Database のユーザー認証 SQL Database のアプリ認証 Azure Web App へのユーザー認証情報の委任 OAuth2 プロトコルとの対比 2
  • 3.
  • 4.
    想定アーキテクチャ 主に Azure WebApp, SQL Database に対する Azure AD 認証を取り扱う 4 ? ? ?
  • 5.
  • 6.
    Office 365 の場合 6 POST/owa/ HTTP/1.1 Host: outlook.office365.com code: AQABAAIAAABeAFzDwllzTY… id_token: eyJ0eXAiOiJKV1QiLCJhbGciO… ③ ログイン画面 HTTP/1.1 302 Found Location: https://login.onmicrosoft.com/common/oauth2/authorize ?client_id=00000002-0000-0ff1-ce00-000000000000 &redirect_uri=https://outlook.office365.com/owa/ &response_type=code+id_token &scope=openid &etc… ⑤ メールボックスが 見られる https://jwt.ms https://outlook.office365.com/owa
  • 7.
  • 8.
  • 9.
    Web アプリで AzureAD 認証を構成するには Web アプリケーション 適切なトークンを持つリクエストに応じたアクセス制御を行う 適切なトークン情報を持たない場合 Azure AD の認可エンドポイントへ誘導する その際に必要とするアプリケーション情報を指定する トークンを返却してもらうための URI を指定する Azure Active Directory アクセスしているユーザーの正当性を確認する 登録されたアプリに対してユーザーの同意を取得する トークンを発行してアプリケーションに返却する 9
  • 10.
    Azure Web Appユーザー認証の動作イメージ Web App は Azure AD を信頼し、認証を委託する ”クライ アント”アプリケーション ユーザーは AAD で認証を受け、 Web App が自身の情報にアクセスすることに同意する Web App は指定のディレクトリで発行された認可コードを持つリクエストを処理する 10 ApplicationEasy Auth
  • 11.
    Azure Web Appユーザー認証の構成 WebApp の認証設定:EasyAuth を使用すると構成が容易 簡易モードであれば AAD へのアプリ登録、設定情報の交換、トークンチェック、トークンがな い場合のリダイレクト、ユーザーアプリへのトークンの伝搬などを自動でやってくれる Azure ポータルで認証に使用している AAD テナントでユーザー認証する場合、かつ、 Azure ポータルのログインユーザーにアプリ登録権限がある場合に限る 11https://docs.microsoft.com/ja-jp/azure/app-service/configure-authentication-provider-aad
  • 12.
    AAD 認証のメリットと留意事項 Azure AD管理者 Office 365 等と同様に 3rd Party 製や自社独自 のアプリを管理できる 全てのアプリで同じ ID 運用・同等の認証強度を提 供することができる 留意事項 不適切なアプリケーションに対して認可コードやトー クンを払い出すのは極めて危険 Azure AD に登録されたアプリケーションが適切なも ののみであるように管理すること アプリケーション開発者 独自のセキュリティ設計・実装・運用をすることなく、ア プリケーションの開発に専念することができる 標準的な認証・認可のプロトコルを採用することで、外 部との相互運用がしやすい 留意事項 認証後に取得した認可コードやトークンが悪用されな いように適切な実装を心がける アプリに対して過大なスコープや権限を持たせないよ うに設計すること 12
  • 13.
  • 14.
    補足 : IaaSやオンプレで実装する場合 EasyAuth がやってくれていた内容をアプリケーションの一 部として実装することになる ミドルウェアや SDK が AAD 認証に対応している場合には、それを使用すると良い 14 OS Web サーバー ミドルウェア アプリケーション 認証ずみリクエストのみを アプリケーションに受け渡す
  • 15.
    補足 : AzureAD Application Proxy オンプレミスでや VM 上で動作する既存の Web サーバーに 対する AAD 認証付きのリバースプロキシ https://docs.microsoft.com/ja-jp/azure/active-directory/manage- apps/application-proxy Azure AD Premium P1 / P2 のライセンスが必要 15 コネクタからの 送信接続でトン ネルを構築 Windows 統合認証 への変換も可能
  • 16.
  • 17.
    SQL Database のAAD 認証の構成と動作 17 サブスクリプション Azure を操作できる 管理者・開発者 データベース管理者 sqladmin データベース利用者 sqluser アプリケーション sqladmin を AD 管理者に設定 sqluser やアプリを データベースロールに追加 Azure Data Studio 等の GUI で 開発・保守・運用作業を行う アクセストークンを用いて データベースに接続 信頼 Azure Active Directory 構成 利用 ユーザーやアプリを登録 Azure Portal や CLI で操作 SSMS や Azure Data Sudio、 Client SDK などで操作 SQL Database に対する アクセストークンが必要
  • 18.
    Azure AD 認証の有効化 SQLDatabase の Active Directory 管理者を指定する 名前がややこしいが、 AD を管理する人ではなく、 SQL DB にアクセスする AAD ユー ザーやアプリケーションを管理する人 18
  • 19.
    SQL DB のAD 管理者によるアクセス AD 管理者は自身の AAD 認証情報を使用して SQL Database にアクセスできる SQL Server Management Studio や Azure Data Studio など、 Azure AD 認証に 対応したクライアントツールを使用 19
  • 20.
    AAD ユーザーの登録 AD 管理者は他のユーザーをSQL DB にユーザー登録、 データベースロールを割り当てることができる この操作は SQL 認証で接続した管理者では実行できない アクセスさせたいユーザーが多数の場合は AAD グループで登録すると良い 20 -- AAD ユーザーの登録 CREATE USER [sqluser1@tenantname.onmicrosoft.com] FROM EXTERNAL PROVIDER; ALTER ROLE db_reader ADD MEMBER [sqluser1@tenantname.onmicrosoft.com]; -- AAD グループの登録 CREATE USER [sqlusers-group] FROM EXTERNAL PROVIDER; ALTER ROLE db_owner ADD MEMBER [sqlusers-group]; T-SQL
  • 21.
    AAD ユーザーによるアクセス SQL DBに登録された AAD ユーザーは AD 管理者と同 様に自身の AAD 認証情報を使用してアクセスできる 複数のユーザーが 1 つの ID/Password を使い回すことなく、日常的に使用している認証 情報を使用してアクセスすることができる(多要素認証にも対応可能) 21
  • 22.
    補足 : AADユーザーによるアクセス アプリケーションコードで AAD ユーザーの認証情報を使用 してアクセスすることも可能 接続文字列で Authentication=Active Directory Password; を指定 ユーザーのパスワード変更や多要素認証に対応できなくなるため、通常は行わない 22 using Microsoft.Data.SqlClient; public SqlConnection CreateAadUserConnection() { var constr = "Server=tcp:servername.database.windows.net,1433;Initial Catalog=dbname;" + "Authentication=Active Directory Password; " + "User ID=sqluser@tenantname.onmicrosoft.com;Password=P@ssw0rd!"; return new SqlConnection(constr); } C# Microsoft.Data.SqlClient パッケージ(https://www.nuget.org/packages/Microsoft.Data.SqlClient/)を使用 実際には環境変数等の 外部に切り出すこと
  • 23.
  • 24.
    AAD アプリによるアクセス ユーザーが介在しない場合は AADにアプリケーションを登 録して SQL DB にアクセスする 常駐型デーモンアプリ、バッチアプリ、 Web アプリなど 接続文字列に埋め込まれた情報ではなく AAD 発行のアクセストークンを使用する 24
  • 25.
    AAD アプリによるアクセス アクセストークンを取得する方法は以下の4パターン ① 新規に作成したサービスプリンシパルのキー(または証明書)を使用する ②AAD 認証設定時に生成されたサービスプリンシパルのキーを使用する ③ システム割り当てマネージド ID を使用する ④ ユーザー割り当てマネージド ID を使用する トークンを取得すれば SqlConnection の作成は同じ 25 using Microsoft.Data.SqlClient; private static SqlConnection GetAadAppTokenConnection() { var token = GetAccessToken(); // トークンの取得方法によって実装を変える var constr = @"Server=tcp:sqlsvrName.database.windows.net,1433;Initial Catalog=dbName;"; var connection = new SqlConnection(constr); connection.AccessToken = token; return connection; } C# 実際には環境変数等の 外部に切り出すこと
  • 26.
    AAD アプリによるアクセス 前述の ①〜④で作成されるサービスプリンシパルに対して SQL Database に対するアクセス権を付与する A) データベースユーザーおよびロールに登録する B) すでにデータベースユーザーおよびロールに登録された AAD グループに追加する 26 -- A) DB 管理者による AAD アプリの登録 CREATE USER [sqlapp_sp] FROM EXTERNAL PROVIDER; ALTER ROLE db_reader ADD MEMBER [sqlapp_sp]; T-SQL
  • 27.
    ① 新規サービスプリンシパルによるアクセス Azure ADにアプリケーション登録権限を持った管理者が下 記の情報を準備 アプリケーション名 アプリケーション ID ディレクトリ ID クライアント シークレット 上記の情報をもとに、前述のように A) SQL DB のユーザーを作成するか B) AAD グループに追加しておく 27 https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-create-service-principal-portal
  • 28.
    ① 新規サービスプリンシパルによるアクセス アプリケーションはキーや証明書を使用して SQLDatabase に対するアクセストークンを取得することができる Azure AD にアクセス可能な環境であれば、必ずしも Azure 上で動作させる必要はなく、 オンプレミスや他社クラウドでも良い 28 using Microsoft.Identity.Client; private static string GetAccessTokenWithServicePrincipal() { var directoryid = "guid-of-your-azuread-directory-id"; var applicatonid = "guid-of-your-application-id"; var clientkey = "key-secret-generated"; var scopes = new[] { "https://database.windows.net/.default" }; var app = ConfidentialClientApplicationBuilder .Create(applicationid) .WithAuthority(new Uri($"https://login.microsoftonline.com/{directoryid}")) .WithClientSecret(clientkey) .Build(); var authresult = app.AcquireTokenForClient(scopes).ExecuteAsync().Result; return authresult.AccessToken; } C# https://www.nuget.org/packages/Microsoft.Identity.Client/ 実際には環境変数等の外部に切り出すこと Azure Web App なら構成情報に記載
  • 29.
    ② 認証設定のサービスプリンシパルを流用 AAD 認証を設定したWeb App は既にAzure AD にアプリ 登録されている 29 Web App と同名のアプリケーションが 登録されているのでこの名前で A) SQL DB のユーザーを作成するか B) AAD グループに追加しておく
  • 30.
    ② 認証設定のサービスプリンシパルを流用 Web Appの認証設定画面の情報は環境変数から取得でき るように設定されている ASP.NET Core アプリケーションであれば Environment.GetEnvironmantVariable() や Configuration で取得できる 30 using Microsoft.Identity.Client; private static string GetAccessTokenFromAppServiceEasyAuth () { var clientid = _config["WEBSITE_AUTH_CLIENT_ID"]; var secret = _config["WEBSITE_AUTH_CLIENT_SECRET"]; var guidpattern = @"([A-Fa-f0-9]{8})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{12})"; var tenantid = Regex.Match(_config["WEBSITE_AUTH_OPENID_ISSUER"], guidpattern).Groups[0].Value; var authority = new Uri($"https://login.microsoftonline.com/{tenantid}"); var scopes = new[] { "https://database.windows.net/.default" }; var app = ConfidentialClientApplicationBuilder .Create(clientid).WithAuthority(authority).WithClientSecret(secret).Build(); var builder = app.AcquireTokenForClient(scopes); var authResult = await builder.ExecuteAsync(); return authResult.AccessToken; } C#
  • 31.
    補足:環境変数の一覧 一度 Web Appで設定される環境設定値を確認するための アプリを作ってデプロイしてみると手っ取り早い 認証設定周りの情報は WEBSITE_AUTH_XXXX に 設定されている 31 <div> <h2>環境変数</h2> <table class="table"> <thead> <tr> <th>Key</th> <th>Value</th> </tr> </thead> <tbody> @foreach (string key in Environment.GetEnvironmentVariables().Keys.OfType<string>()) { <tr> <td><span>@key</span></td> <td><span>@(Environment.GetEnvironmentVariable(key))</span></td> </tr> } </tbody> </table> </div> ASP.NET Core
  • 32.
    ③ システム割当マネージ IDを使用したアクセス Web App にマネージド ID を割り当てておくと、そこで動作 するアプリがトークンを取得するエンドポイントが用意される この場合も Web App と同じ名前のサービスプリンシパルが AAD に作成される 32 https://docs.microsoft.com/ja-jp/azure/app-service/overview-managed-identity?tabs=dotnet Web App と同名のアプリケーションが 登録されているのでこの名前で A) SQL DB のユーザーを作成するか B) AAD グループに追加しておく
  • 33.
    ③ システム割当マネージ IDを使用したアクセス Web App にデプロイされたアプリは実行環境からマネージ ド ID を使用してアクセストークンを取得することができる アクセストークンの取得は Azure AD のトークンエンドポイントではなく、Web App 環境内に 用意されるエンドポイントを使用する ASP.NET Core の場合は System.Net.Http や Json.NET などを使用する 33 using System.Net.Http; using Newtonsoft.Json.Linq; private static async Task<string> GetAccessTokenFromSystemAssignedManagedId() { var resourceuri = "https%3A%2F%2Fdatabase.windows.net%2F"; var msiurl = string.Format("{0}?resource={1}&api-version=2017-09-01", _config["MSI_ENDPOINT"], resourceuri); string token = null; using (var hc = new HttpClient()) { hc.DefaultRequestHeaders.Add("Secret", _config["MSI_SECRET"]); var ret = await hc.GetStringAsync(msiurl); token = JObject.Parse(ret)["access_token"].ToString(); } return token; } C# マネージ ID 用のトークンエンドポイント URL が設定され ている環境変数を使用して下記 URL を組み立てている http://127.0.0.1:41631/MSI/token/ ?resource=http://database.windows.net &api-version=2017-09-01
  • 34.
    ③ システム割当マネージ IDを使用したアクセス マネージド ID を使用してアクセストークンを取得する専用の ライブラリが提供されている場合はそちらを使うと良い ASP.NET Core の場合は Microsoft.Azure.Services.AppAuthentication が利用で きる 34 using Microsoft.Azure.Services.AppAuthentication; private static async Task<string> GetAccessTokenFromSystemAssignedManagedId() { var provider = new AzureServiceTokenProvider(); var token = await provider.GetAccessTokenAsync("https://database.windows.net/"); return token; } C# アクセストークンを取得した い対象リソースの URI だけ 指定すれば良い
  • 35.
    ④ ユーザ割当マネージ IDを利用したアクセス ユーザー割り当てマネージ ID は柔軟な構成が可能 1つのマネージ ID を複数の WebApp や VM に割り当てて共用する 1つの Web App に対して複数のマネージ ID を割り当てアクセス先に応じて使い分けるこ とができる 35 対象となる Web App に割り当てる マネージ ID と同名のサービスプリンシ パルが登録されているのでこの名前で A) SQL DB のユーザーを作成するか B) AAD グループに追加しておく
  • 36.
    ④ ユーザ割当マネージ IDを利用したアクセス アクセストークンの取得クライアント ID を指定する以外システ ム割当の場合とほぼ同じ 36 using System.Net.Http; using Newtonsoft.Json.Linq; private static async Task<string> GetAccessTokenFromSystemAssignedManagedId() { string token = null; using (var hc = new HttpClient()) { var resourceuri = "https%3A%2F%2Fdatabase.windows.net%2F"; var msiurl = string.Format("{0}?resource={1}&api-version=2017-09-01&clientid={2}" , _config["MSI_ENDPOINT"], resourceuri, "guid-of-clientid-for-uamid"); hc.DefaultRequestHeaders.Add("Secret", _config["MSI_SECRET"]); var ret = await hc.GetStringAsync(msiurl); token = JObject.Parse(ret)["access_token"].ToString(); } return token; } C#
  • 37.
    Tips : AADユーザーの確認 SQL Database に登録した AAD ユーザーやグループおよ びデータベースロールは下記のように確認できる 37 SELECT DP1.name AS DatabaseRoleName, isnull (DP2.name, 'No members') AS DatabaseUserName , DP2.type_desc as PrincipalType, DP2.sid FROM sys.database_role_members AS DRM RIGHT OUTER JOIN sys.database_principals AS DP1 ON DRM.role_principal_id = DP1.principal_id LEFT OUTER JOIN sys.database_principals AS DP2 ON DRM.member_principal_id = DP2.principal_id WHERE DP1.type = 'R' ORDER BY DP1.name; T-SQL
  • 38.
    Tips:現在の SQL セッションのユーザー SQLDatabase に接続できたら現在どのユーザーで接続 しているのかを確認してみると良い 38 using Microsoft.Data.SqlClient; private static async Task OnGet() { var connection = GetAadAppTokenConnection(); try { await connection.OpenAsync(); using ( var cmd = connection.CreateCommand() ) { cmd.CommandText = "select suser_name()"; var dbuser = cmd.ExecuteScalar().ToString(); } } finally { connection.Close(); } } C#
  • 39.
    Tips : アプリ名の重複 WebApp の以下の操作で ”同名のサービスプリンシパル” が作成され、SQL DB への登録時に区別がつかない AAD ユーザー認証を構成する システム割当マネージ ID を有効にする 39 ユーザー認証(簡易モード)で作成された サービスプリンシパル マネージ ID で作成されたサービスプリンシパル -- A) DB 管理者による AAD アプリの登録 CREATE USER [ainaba-aadauth-web] FROM EXTERNAL PROVIDER; T-SQL
  • 40.
    Tips : アプリ名の重複 回避策としては以下が考えられる ユーザー認証では簡易モードを使用しない(アプリ登録時に名前を指定できる) ユーザー割当マネージドID を使用する(マネージド ID 作成時に名前を指定できる) SQL DB にアクセス可能な AAD グループに登録する(Azure ポータルで区別:下記参照) ユーザー登録時に sid を明示的に指定して名前をずらす(次ページ) 40 オブジェクト ID で 区別がつく
  • 41.
    Tips : アプリ名の重複 SQLDB への登録時に SID を使用してアプリケーションを 明示的に指定することができる 41 ## アプリケーション ID から SID を生成 PS> $b = [Guid]::Parse("eb49934f-…").ToByteArray() PS> "0x" + (($b | % {$_.ToString("X2")}) –join "") 0x4F9349EB85BD… PowerShell -- sid を指定することで AAD アプリとは別名をつける CREATE USER [ainaba-aadauth-web-mi2] with sid = 0x4F9349EB85BD…, type = E; -- 別名のユーザーをデータベースロールに追加 ALTER ROLE db_owner ADD MEMBER [ainaba-aadauth-web-mi2]; T-SQL
  • 42.
    補足: VM でアプリが動作する場合 アプリがAzure VM 上で動作する場合も同様の実装が可能 だがいくつか差異が発生する AAD ユーザー認証を自動構成してくれる簡易機能は提供されない > 対応する Web アプリの認証するライブラリを利用して自力で実装する サービスプリンシパルのキー情報などは環境変数に自動設定されない > 自力で環境変数に設定するか、構成設定ファイルやレジストリで管理する マネージ ID によるトークンエンドポイントが異なる > URL が異なる程度だがコードの流用時に注意 システム割当マネージ ID は VM インスタンスごとに異なるオブジェクトになる > ユーザー割当マネージ ID や AAD グループによる管理を検討する 詳細は下記の Blog などを参照 https://ayuina.github.io/ainaba-csa-blog/sqldb-aad-authentication/ 42
  • 43.
  • 44.
    ユーザー認証の委任(Delegate) アプリケーションが DB アクセスする際に、アクセス元のユー ザーのふりをしてアクセスすることも出来る AzureAD に登録された Web アプリに対して SQL DB アクセスを委任する SQL DB も Azure AD にアプリとして登録されている (022907d3-0f1b-48f7-badc-1ba6abab6d66) 44
  • 45.
    Web App によるアクセストークンの自動取得 ユーザー認証が有効になっているWeb App であれば、 SQL DB のアクセストークンも取得を任せることができる Web App の認証時に SQL DB へのアクセストークンも発行するように構成 Microsoft.Web/sites/appName/config/authsettings/properties/additionalLoginParams 45 // ポータルでは設定できないので Resource Explorer 等で // 認証設定のオプションを指定 additionalLoginParams : [ "response_type=code id_token", "resource=https://database.windows.net" ] ARM
  • 46.
    Web App によるアクセストークンの自動取得 WebApp が取得したアクセストークンをそのまま SQL Connection に設定するだけで良い EasyAuth によって X-MS-TOKEN-AAD-ACCESS-TOKEN ヘッダーに設定される 46 private static async Task<string> GetAccessTokenAsUser() { return Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"]; } C# Easy Auth App X-MS-TOKEN-AAD- ACCESS-TOKEN SQL Connection
  • 47.
  • 48.
    アプリ側でアクセストークンを取得する こちらの手法であれば任意のタイミングに任意のリソースに対 してアクセストークンを取得できる 48 private static asyncTask<string> GetAccessTokenAsUser() { var clientid = _config["WEBSITE_AUTH_CLIENT_ID"]; var secret = _config["WEBSITE_AUTH_CLIENT_SECRET"]; var guidpattern = @"([A-Fa-f0-9]{8})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{4})¥-([A-Fa-f0-9]{12})"; var tenantid = Regex.Match(_config["WEBSITE_AUTH_OPENID_ISSUER"], guidpattern).Groups[0].Value; var authority = new Uri($"https://login.microsoftonline.com/{tenantid}"); var scopes = new[] { "https://database.windows.net/.default" }; var app = ConfidentialClientApplicationBuilder .Create(clientid).WithAuthority(authority).WithClientSecret(secret).Build() as IByRefreshToken; var authcode = Request.Headers["X-MS-TOKEN-AAD-REFRESH-TOKEN"][0]; var builder = app.AcquireTokenByRefreshToken(scopes, authcode); var result = await builder.ExecuteAsync(); return result.AccessToken; } ARM
  • 49.
    補足:HTTP ヘッダー情報の一覧 一度 WebApp で動作するアプリが受け取るリクエストヘッ ダーを確認するアプリを作ってデプロイしてみると早い Web App にアクセスしているユーザー情報は X-MS-CLIENT-PRINCIPAL-XXXX で AAD から渡されるトークン関係の情報は X-MS-TOKEN-AAD-XXXX で取得できる 49 <div> <h2>HTTP リクエストヘッダー</h2> <table class="table"> <thead> <tr> <th>Key</th> <th>Value</th> </tr> </thead> <tbody> @foreach (string key in string key in Request.Headers.Keys.OfType<string>()) { <tr> <td><span>@key</span></td> <td><span>@(Request.Headers[key])</span></td> </tr> } </tbody> </table> </div> ASP.NET Core
  • 50.
  • 51.
    Web App のサインイン 51 ①サインインしていないリクエストを Azure AD にリダイレクト https://login.microsoftonline.com/{tenant}/oauth2/authorize ?response_type=code+id_token &redirect_uri=https://{appName}.azurewebsites.net/.auth/login/aad/callback &client_id={guid-of-application-registered} &scope=openid+profile+email &response_mode=form_post &nonce=xxxxxxx &state=xxxxxxx OAuth 2.0 承認エンドポイント を使用した Open ID Connect およ び ② サインイン(およびユーザーの同意) 登録されたアプリ(client_id, redirect_uri)である ことを確認し、ユーザーのサインイン操作に応じて、認 可コード(code)と ID トークン(id_token)を返却 ③ コールバック Web App の指定されたコールバック URL に認可コード(code)と ID トークン (id_token)をポスト(form_post) ④ 認証クッキーの発行 提示された認可コード(code)と ID トークン (id_token)を確認し、認証状態を維持するための クッキー AppServiceAuthSession を発行 ⑤ アプリケーションの利用 以降のリクエストに認証クッキーを 付与することで認証済みユーザーと してアプリケーションを利用 ⑥ アプリケーションの動作 EasyAuth がリクエストヘッダーに 設定した各種トークン等を活用して API アクセスなどを行う
  • 52.
    SQL Database への委任アクセス 52 ⑦ユーザーの認可コードを使用してアクセストークンを取得 POST /{tenant}/oauth2/v2.0/token HTTP/1.1 Host: https://login.microsoftonline.com Content-Type: application/x-www-form-urlencoded client_id={guid-of-application-registered} &scope=https://database.windows.net/.default &code={authorization_code} &redirect_uri=https://{appName}.azurewebsites.net/.auth/login/aad/c allback &grant_type=authorization_code &client_secret={secretKeyOfApplication} OAuth 2.0 トークンエンドポイント を使用した Authorization Code Flow ⑧ アクセストークンを提示 SqlConnection オブジェクトの AccessToken プロパティにセット ⑨ アクセス制御 SQL DB の登録ユーザーおよび データベースロールを確認 サインイン時にアプリが認可 コードを用いてアクセストークン を取得することを委任
  • 53.
    SQL Database へのアプリケーションアクセス 53 ① アプリケーションとしてアクセストークンを取得 POST /{tenant}/oauth2/v2.0/token HTTP/1.1 Host: login.microsoftonline.com Content-Type: application/x-www-form-urlencoded client_id={guid-of-application-registered} &scope=https://database.windows.net/.default &client_secret={secretKeyOfApplication} &grant_type=client_credentials OAuth 2.0 トークンエンドポイント を使用した Client Credentials Grant Flow ② アクセストークンを提示 SqlConnection オブジェクトの AccessToken プロパティにセット ③ アクセス制御 SQL DB の登録ユーザーおよび データベースロールを確認 ユーザーは関与しない
  • 54.
    リファレンス Open ID Connect https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2- protocols-oidc AuthorizationCode Flow https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2- oauth2-auth-code-flow Client Credentials Flow https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2- oauth2-client-creds-grant-flow 54
  • 55.
    MICROSOFT CONFIDENTIAL 本資料は情報提供のみを⽬的としており、本資料に記載されている情報は、本資料作成時点でのマイクロソフトの⾒解を⽰し たものです。状況等の変化により、内容は変更される場合があります。本資料に表記されている内容(提⽰されている条件等 を含みます)は、貴社との有効な契約を通じて決定されます。それまでは、正式に確定するものではありません。従って、本資 料の記載内容とは異なる場合があります。また、本資料に記載されている価格はいずれも、別段の表記がない限り、参考価 格となります。貴社の最終的な購⼊価格は、貴社のリセラー様により決定されます。マイクロソフトは、本資料の情報に対して 明⽰的、黙⽰的または法的な、いかなる保証も⾏いません。 © 2019Microsoft Corporation. All rights reserved. MICROSOFT CONFIDENTIAL 本資料は情報提供のみを⽬的としており、本資料に記載されている情報は、本資料作成時点でのマイクロソフトの⾒解を⽰し たものです。状況等の変化により、内容は変更される場合があります。本資料に表記されている内容(提⽰されている条件等 を含みます)は、貴社との有効な契約を通じて決定されます。それまでは、正式に確定するものではありません。従って、本資 料の記載内容とは異なる場合があります。また、本資料に記載されている価格はいずれも、別段の表記がない限り、参考価 格となります。貴社の最終的な購⼊価格は、貴社のリセラー様により決定されます。マイクロソフトは、本資料の情報に対して 明⽰的、黙⽰的または法的な、いかなる保証も⾏いません。 © 2019 Microsoft Corporation. All rights reserved.