ラベル Windows Azure Active Directory の投稿を表示しています。 すべての投稿を表示
ラベル Windows Azure Active Directory の投稿を表示しています。 すべての投稿を表示

2015年1月17日土曜日

[AzureAD]管理者アカウントでAzureにサインアップする

AzureAD上に作成(もしくはオンプレミスADから同期)したユーザに全体管理者ロールを与えておき、そのユーザで別のAzureサブスクリプションへサインアップするとどうなるのか?を試してみました。

前々回のポストで全体管理者としてアサインしたユーザが他のユーザ情報を参照・編集してしまうのを防ぐには、という話題で初期状態で管理ポータルへアクセス出来ないので、、ということを紹介しました。
ただし、その管理者アカウントでAzureサブスクリプションを新規にサインアップしてしまえば管理ポータルにアクセスできてしまうので、やはり注意が必要です。
これを防ぐには前回のポストで紹介したようにWebアプリケーションの認証を行う際にIdPへネットワーク的にアクセスできないように構成するなど別の対策が必要になります。

実際にどうなるのかを試してみます。(かなり当たり前な結果ばかりですが)
全体管理者アカウントでサインアップして管理ポータルにアクセスすると以下のような状態になります。


最初から自分が管理者となっているAzure Active Directory(AzureAD)のディレクトリが見えています。

開いてみると、当然全ての操作が可能です。


柔軟に色々なことができるAzureADのアイデンティティ管理ですが、何をしたら何が起きるかをしっかり把握しておかないと危ないので、しっかり把握しておくことが大切です。

尚、当該のアカウントに多要素認証設定をしておくと最初からアカウントの管理メニューに追加の認証に関する項目が出てきます。(ちなみにこのユーザ、OpenAMで認証するように構成してあるユーザなので、ポータルにアクセスすると、OpenAMにリダイレクトされ認証された後、AzureADの多要素認証が実行されます)


2014年11月18日火曜日

[AADSync]フルパスワード同期を強制的に実行する

先日Azure Active Directory Synchronization Services(AADSync)にもパスワード同期機能が実装された、という話を書きました。
 http://idmlab.eidentity.jp/2014/11/aadsync.html

しかし、ディレクトリ同期ツール(DirSync)にあって、AADSyncにない機能があり、その一つがパスワードの強制同期機能です。

DirSyncではフォーラムのFAQに書かれているように'Set-FullPasswordSync'コマンドレットを実行してサービスを再起動すればパスワードの強制同期が出来ました。

 フォーラムURL:
  http://social.technet.microsoft.com/wiki/contents/articles/18096.dirsync-password-sync-frequently-asked-questions.aspx

 パスワードの強制同期方法(PowerShell)
Import-Module DirSync
Set-FullPasswordSync
Restart-Service FIMSynchronizationService



一方でAADSyncには先にポストしたPowerShellコマンドレット一覧を見ても'Set-FullPasswordSync'が見当たりません。

MSDNフォーラムで色々と情報を探していたんところ、MirosoftのMarkus VilcinskasがTechnet Wikiに書いてくれました。かなり強引な方法ですので、いずれちゃんとしたコマンドレットが用意される気がしますが。

 Technet Wiki - How to Use PowerShell to Trigger a Full Password Sync in Azure AD Sync
  http://social.technet.microsoft.com/wiki/contents/articles/28433.how-to-use-powershell-to-trigger-a-full-password-sync-in-azure-ad-sync.aspx

$adConnector  = "mydomain.local"
$aadConnector = "mytenant.onmicrosoft.com - AAD"

Import-Module ADSync
$c = Get-ADSyncConnector -Name $adConnector
$p = New-Object Microsoft.IdentityManagement.PowerShell.ObjectModel.ConfigurationParameter "MicrosoftSynchronize.ForceFullPasswordSync", String, ConnectorGlobal, $null, $null, $null
$p.Value = 1
$c.GlobalParameters.Remove($p.Name)
$c.GlobalParameters.Add($p)
$c = Add-ADSyncConnector -Connector $c
 
Set-ADSyncAADPasswordSyncConfiguration -SourceConnector $adConnector -TargetConnector $aadConnector -Enable $false
Set-ADSyncAADPasswordSyncConfiguration -SourceConnector $adConnector -TargetConnector $aadConnector -Enable $true



ちなみに各コネクタの名称はSynchronization Service Managerで確認できます。(TypeがActive Directory Domain ServicesとなっているものがオンプレミスADコネクタ、Windows Azure Active Directory (Microsoft)となっているの*.onmicrosoft.com -ADという名前のものがAzureADコネクタです)
さっそく実行してみると、イベントログにパスワード同期が実行されたことが記録されます。


基本的に2分に一回パスワードは同期されますし、ネットワーク障害などで更新が出来なかったときはリトライがされるので大きな問題になることは少ないとは思いますが、メンテナンス時など強制的に全同期をしておきたい時もあると思いますので、そのような際はこのコマンドを使えば良いですね。


2014年11月13日木曜日

[AADSync]PowerShellコマンドレット一覧

ディレクトリ同期ツール(DirSync)でもPowerShellモジュールが用意されていましたが、当然Azure Active Directory Synchronization Services(AADSync)にも用意されています。

個々の詳しい内容は機会があれば紹介したいと思いますが、とりあえずモジュール名と使えるコマンドレット名の一覧を書いておきます。

◆モジュール名
Get-Module -ListAvailableを実行すると「ADSync」という名前であることがわかります。
(ディレクトリ同期ツールでは「DirSync」でした)

Directory: C:\Program Files\Microsoft Azure AD Sync\Bin

ModuleType Version    Name    ExportedCommands
---------- -------    ----    ----------------
Binary     1.0.0.0    ADSync  {Get-ADSyncConnector, New-ADSyncConnector, Add-ADSyncConne...


◆コマンドレット一覧
先ほどのADSyncをVerboseモードでインポートすると一覧が取得できます。

PS C:\Users\Administrator> Import-Module ADSync -Verbose
VERBOSE: Loading module from path 'C:\Program Files\Microsoft Azure AD Sync\Bin\ADSync\ADSync.psd1'.
VERBOSE: Loading 'Assembly' from path 'C:\Program Files\Microsoft Azure AD
Sync\Bin\Microsoft.CredentialManagement.OnPremisesPasswordReset.Shared.dll'.
VERBOSE: Loading 'Assembly' from path 'C:\Program Files\Microsoft Azure AD
Sync\Bin\Microsoft.MetadirectoryServices.AADPasswordReset.Types.dll'.
VERBOSE: Loading 'Assembly' from path 'C:\Program Files\Microsoft Azure AD
Sync\Bin\Microsoft.CredentialManagement.OnPremisesPasswordReset.Library.dll'.
VERBOSE: Loading 'Assembly' from path 'C:\Program Files\Microsoft Azure AD Sync\Bin\Microsoft.ServiceBus.dll'.
VERBOSE: Loading 'Assembly' from path 'C:\Program Files\Microsoft Azure AD Sync\Bin\Newtonsoft.Json.dll'.
VERBOSE: Loading module from path 'C:\Program Files\Microsoft Azure AD
Sync\Bin\ADSync\Microsoft.IdentityManagement.PowerShell.Cmdlet.dll'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnector'.
VERBOSE: Exporting cmdlet 'New-ADSyncConnector'.
VERBOSE: Exporting cmdlet 'Add-ADSyncConnector'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncConnector'.
VERBOSE: Exporting cmdlet 'Add-ADSyncConnectorAnchorConstructionSettings'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncConnectorAnchorConstructionSettings'.
VERBOSE: Exporting cmdlet 'Add-ADSyncConnectorHierarchyProvisioningMapping'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnectorHierarchyProvisioningDNComponent'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnectorHierarchyProvisioningMapping'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnectorHierarchyProvisioningObjectClass'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncConnectorHierarchyProvisioningMapping'.
VERBOSE: Exporting cmdlet 'Add-ADSyncConnectorAttributeInclusion'.
VERBOSE: Exporting cmdlet 'Add-ADSyncConnectorObjectInclusion'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncConnectorAttributeInclusion'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncConnectorObjectInclusion'.
VERBOSE: Exporting cmdlet 'Disable-ADSyncConnectorPartition'.
VERBOSE: Exporting cmdlet 'Disable-ADSyncConnectorPartitionHierarchy'.
VERBOSE: Exporting cmdlet 'Enable-ADSyncConnectorPartition'.
VERBOSE: Exporting cmdlet 'Enable-ADSyncConnectorPartitionHierarchy'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnectorPartition'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnectorPartitionHierarchy'.
VERBOSE: Exporting cmdlet 'Update-ADSyncConnectorPartition'.
VERBOSE: Exporting cmdlet 'Add-ADSyncRunStep'.
VERBOSE: Exporting cmdlet 'Get-ADSyncRunProfile'.
VERBOSE: Exporting cmdlet 'New-ADSyncRunProfile'.
VERBOSE: Exporting cmdlet 'Add-ADSyncRunProfile'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncRunProfile'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncRunStep'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnectorTypes'.
VERBOSE: Exporting cmdlet 'Get-ADSyncGlobalSettings'.
VERBOSE: Exporting cmdlet 'Set-ADSyncGlobalSettings'.
VERBOSE: Exporting cmdlet 'Add-ADSyncGlobalSettingsParameter'.
VERBOSE: Exporting cmdlet 'Get-ADSyncGlobalSettingsParameter'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncGlobalSettingsParameter'.
VERBOSE: Exporting cmdlet 'Get-ADSyncConnectorParameter'.
VERBOSE: Exporting cmdlet 'Set-ADSyncConnectorParameter'.
VERBOSE: Exporting cmdlet 'Get-ADSyncAADPasswordResetConfiguration'.
VERBOSE: Exporting cmdlet 'Get-ADSyncAADPasswordSyncConfiguration'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncAADPasswordResetConfiguration'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncAADPasswordSyncConfiguration'.
VERBOSE: Exporting cmdlet 'Set-ADSyncAADPasswordResetConfiguration'.
VERBOSE: Exporting cmdlet 'Set-ADSyncAADPasswordSyncConfiguration'.
VERBOSE: Exporting cmdlet 'Set-MIISADMAConfiguration'.
VERBOSE: Exporting cmdlet 'Get-ADSyncSchema'.
VERBOSE: Exporting cmdlet 'Set-ADSyncSchema'.
VERBOSE: Exporting cmdlet 'Update-ADSyncConnectorSchema'.
VERBOSE: Exporting cmdlet 'Set-ADSyncAADPasswordSyncState'.
VERBOSE: Exporting cmdlet 'Set-ADSyncServerConfiguration'.
VERBOSE: Exporting cmdlet 'Get-ADSyncServerConfiguration'.
VERBOSE: Exporting cmdlet 'Get-ADSyncRule'.
VERBOSE: Exporting cmdlet 'New-ADSyncRule'.
VERBOSE: Exporting cmdlet 'Add-ADSyncRule'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncRule'.
VERBOSE: Exporting cmdlet 'Add-ADSyncAttributeFlowMapping'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncAttributeFlowMapping'.
VERBOSE: Exporting cmdlet 'Add-ADSyncJoinConditionGroup'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncJoinConditionGroup'.
VERBOSE: Exporting cmdlet 'New-ADSyncJoinCondition'.
VERBOSE: Exporting cmdlet 'Add-ADSyncScopeConditionGroup'.
VERBOSE: Exporting cmdlet 'Remove-ADSyncScopeConditionGroup'.
VERBOSE: Exporting cmdlet 'New-ADSyncScopeCondition'.
VERBOSE: Importing cmdlet 'Add-ADSyncAttributeFlowMapping'.
VERBOSE: Importing cmdlet 'Add-ADSyncConnector'.
VERBOSE: Importing cmdlet 'Add-ADSyncConnectorAnchorConstructionSettings'.
VERBOSE: Importing cmdlet 'Add-ADSyncConnectorAttributeInclusion'.
VERBOSE: Importing cmdlet 'Add-ADSyncConnectorHierarchyProvisioningMapping'.
VERBOSE: Importing cmdlet 'Add-ADSyncConnectorObjectInclusion'.
VERBOSE: Importing cmdlet 'Add-ADSyncGlobalSettingsParameter'.
VERBOSE: Importing cmdlet 'Add-ADSyncJoinConditionGroup'.
VERBOSE: Importing cmdlet 'Add-ADSyncRule'.
VERBOSE: Importing cmdlet 'Add-ADSyncRunProfile'.
VERBOSE: Importing cmdlet 'Add-ADSyncRunStep'.
VERBOSE: Importing cmdlet 'Add-ADSyncScopeConditionGroup'.
VERBOSE: Importing cmdlet 'Disable-ADSyncConnectorPartition'.
VERBOSE: Importing cmdlet 'Disable-ADSyncConnectorPartitionHierarchy'.
VERBOSE: Importing cmdlet 'Enable-ADSyncConnectorPartition'.
VERBOSE: Importing cmdlet 'Enable-ADSyncConnectorPartitionHierarchy'.
VERBOSE: Importing cmdlet 'Get-ADSyncAADPasswordResetConfiguration'.
VERBOSE: Importing cmdlet 'Get-ADSyncAADPasswordSyncConfiguration'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnector'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnectorHierarchyProvisioningDNComponent'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnectorHierarchyProvisioningMapping'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnectorHierarchyProvisioningObjectClass'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnectorParameter'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnectorPartition'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnectorPartitionHierarchy'.
VERBOSE: Importing cmdlet 'Get-ADSyncConnectorTypes'.
VERBOSE: Importing cmdlet 'Get-ADSyncGlobalSettings'.
VERBOSE: Importing cmdlet 'Get-ADSyncGlobalSettingsParameter'.
VERBOSE: Importing cmdlet 'Get-ADSyncRule'.
VERBOSE: Importing cmdlet 'Get-ADSyncRunProfile'.
VERBOSE: Importing cmdlet 'Get-ADSyncSchema'.
VERBOSE: Importing cmdlet 'Get-ADSyncServerConfiguration'.
VERBOSE: Importing cmdlet 'New-ADSyncConnector'.
VERBOSE: Importing cmdlet 'New-ADSyncJoinCondition'.
VERBOSE: Importing cmdlet 'New-ADSyncRule'.
VERBOSE: Importing cmdlet 'New-ADSyncRunProfile'.
VERBOSE: Importing cmdlet 'New-ADSyncScopeCondition'.
VERBOSE: Importing cmdlet 'Remove-ADSyncAADPasswordResetConfiguration'.
VERBOSE: Importing cmdlet 'Remove-ADSyncAADPasswordSyncConfiguration'.
VERBOSE: Importing cmdlet 'Remove-ADSyncAttributeFlowMapping'.
VERBOSE: Importing cmdlet 'Remove-ADSyncConnector'.
VERBOSE: Importing cmdlet 'Remove-ADSyncConnectorAnchorConstructionSettings'.
VERBOSE: Importing cmdlet 'Remove-ADSyncConnectorAttributeInclusion'.
VERBOSE: Importing cmdlet 'Remove-ADSyncConnectorHierarchyProvisioningMapping'.
VERBOSE: Importing cmdlet 'Remove-ADSyncConnectorObjectInclusion'.
VERBOSE: Importing cmdlet 'Remove-ADSyncGlobalSettingsParameter'.
VERBOSE: Importing cmdlet 'Remove-ADSyncJoinConditionGroup'.
VERBOSE: Importing cmdlet 'Remove-ADSyncRule'.
VERBOSE: Importing cmdlet 'Remove-ADSyncRunProfile'.
VERBOSE: Importing cmdlet 'Remove-ADSyncRunStep'.
VERBOSE: Importing cmdlet 'Remove-ADSyncScopeConditionGroup'.
VERBOSE: Importing cmdlet 'Set-ADSyncAADPasswordResetConfiguration'.
VERBOSE: Importing cmdlet 'Set-ADSyncAADPasswordSyncConfiguration'.
VERBOSE: Importing cmdlet 'Set-ADSyncAADPasswordSyncState'.
VERBOSE: Importing cmdlet 'Set-ADSyncConnectorParameter'.
VERBOSE: Importing cmdlet 'Set-ADSyncGlobalSettings'.
VERBOSE: Importing cmdlet 'Set-ADSyncSchema'.
VERBOSE: Importing cmdlet 'Set-ADSyncServerConfiguration'.
VERBOSE: Importing cmdlet 'Set-MIISADMAConfiguration'.
VERBOSE: Importing cmdlet 'Update-ADSyncConnectorPartition'.
VERBOSE: Importing cmdlet 'Update-ADSyncConnectorSchema'.


基本はGUIツール(構成ウィザード、ルールエディタ、同期マネージャ)で出来ることはPowerShellで出来そうですね。

Office2013 Windowsクライアントが多要素認証とSAML IdPサポート

ずいぶん前から「そのうち」と言われていて中々実現しなかったOfficeのネイティブアプリでの多要素認証(MFA)と外部SAML IdPでの認証サポートが今月後半に実現することが発表されました。

Officeの公式blog




※blogより転載

なるほど、ADAL(Active Directory Authentication Library)をOfficeクライアントの認証コードに噛ませてAzure ADや外部IdPとつなげる、という構成なわけです。

これでAzure ADからOAuthのアクセストークンを取得してOffice365のサービスへOfficeクライアントがアクセスするわけですね。


blogによると、以下のことが出来るようになるようです。

1.多要素認証

 いわゆるPhoneFactorとかの追加要素を使った認証ですね。

2.SAML対応の外部IdPでの認証

 現在もMicrosofot Online Sign-In Assistantを使ってAzure ADを使って認証をすることはできましたが、中身はws-trustを使っていたので、実質Azure AD一択でした。しかし、今回ADALを使うことでSAML2.0に対応するので、OpenAMなどと直接接続をすることが出来るようになります。

3.SmartCard認証

 多要素認証の一環でもありますが、AD FSを展開していてSmartCardで認証できるようにしている環境下において、ID/パスワードを入力する代わりにSmartCardのみで認証できるようになります。

4.OutlookでのBASIC認証が不要に

 これまでOutlookとOffice365(Exchange Online)の間はBASIC認証でしたので、ID/パスワードをOutlookからExchangeへ渡して、Exchange Onlineがws-trustでAzure ADやAD FSで認証される、という構成でしたが、ADALをサポートすることでOutlookから直接IdPへ接続し認証後、Exchange Onlineへ接続、という流れに変わります。
 ※おそらく、これでAD FS+Office365+Outlook環境でAD FS Proxyが必要なくなります。


Microsoft Updateで更新プログラムが落ちてくるみたいなので、月末が楽しみです。
また、待ちきれない人に向けてPreview Programもやっているみたいなので、興味がある方は参加してみてはいかがでしょうか?



[AADSync]パスワード同期機能が追加

正式版がリリースされてから時間が経っているにも関わらず全くblogで紹介することなくスルーしてしまっていたAzure Active Directory Synchronization Services(AADSync)ですが、10月の終わりに新ビルドがリリースされています。


ダウンロードサイト(1.0.0470.1023)
 http://www.microsoft.com/en-us/download/details.aspx?id=44225

GA版からの変化点は以下の2点です。

  1. 構成ウィザードがローカライズされた
  2. パスワード同期(オンプレミスAD⇒AzureAD)がサポートされた


1点目のローカライズですが、こんな感じで進化してきています。
 ベータ版:英語環境にしかインストールできない
 GA版:日本語環境にもインストールが出来る(表示は英語)
 新バージョン:構成ウィザードがローカライズされた


ただ、Synchronization Rules EditorやSynchronization Service Managerは相変わらず英語表記です。




次にパスワード同期ですが、ディレクトリ同期ツールでは提供されていた機能がAAD Syncにも実装されてきました。
基本的な仕様や使い方はディレクトリ同期ツールとほぼ同じです。(PowerShellのコマンドレット名が違うくらい)

構成ウィザードの中のオプション機能を選択する画面でパスワード同期にチェックを入れればパスワード(のハッシュ)がオンプレミスのADからAzure ADへ同期されるようになります。


尚、パスワード同期機能を使うためにはAAD Syncに指定したオンプレミスADとの接続に使うユーザに対して以下の権限を付与する必要があります。(Administratorユーザを指定した場合は不要です)
<追加で必要な権限>

  • ディレクトリの変更のレプリケート
  • ディレクトリの変更をすべてにレプリケート


追加方法はActive Directoryユーザとコンピュータより「制御の委任」で行います。

ドメインのルートを右クリックし、[制御の委任]をクリックします。


[委任するカスタムタスクを作成する]を選択します。


[このフォルダー、このフォルダー内の既存のオブジェクト、およびこのフォルダー内の新しいオブジェクトの作成]を選択しウィザードを進めます。


アクセス許可の選択しより「ディレクトリの変更のレプリケート」と「ディレクトリの変更をすべてにレプリケート」にチェックを入れます。




最後に確認してウィザードの構成を終わり、AAD Syncのサービスを再起動します。


うまく同期されればイベントビューアに以下のようなログが記録されます。
(失敗した場合はペンディングリストに入りリトライされます)



※その他注意点
・IPv6が有効な環境でパスワード同期を行う場合は、Azure ADとの接続にIPv6が優先されるため、途中のルータなどでIPv6が通らない場合は同期に失敗する
 (単純なアカウント同期だけだとIPv6⇒IPv4にフォールバックしてくれているのか、問題は発生しません)
 ※Office365 MVPの@genkiwさんの以前の記事の状況と同じだと思われます。
  http://blog.o365mvp.com/2013/03/19/waad_connecting_issue/
・既に構成済みのAAD Syncに後からパスワード同期を有効化する場合、Synchronization Service ManagerからオンプレミスADとAzure ADの各Management AgentのFull Import -> Full Synchronizationを実行する必要があるようです。いずれにしても構成ウィザードを起動する際にWindowsタスクでAAD Syncの同期タスクを無効化する必要があるので、構成ウィザードが完了した後は、手動でFull Import -> Full Synchronizationを実行してから同期タスクを有効化した方が安全です。




ディレクトリ同期やForefront Identity Manager(FIM)+Azure AD Connectorと比較して機能面でも充実していますし、同期設定のカスタマイズも容易になっているので今後はAzure AD / Office365を使う場合はAAD Sync一択になりそうです。

2014年9月7日日曜日

続Azure ADのSAML対応(IdP編)~SP Initiatedに対応

前回のPOSTで現状Azure Active DirectoryのSAML IdP対応はIdP Initiatedだけ、という話をしましたが、直近(9/3)のアップデートでSP Initiatedに対応しました。

 TechnetのActive Directory Teamのブログ
 - 50+ SaaS Apps and growing now support federation with Azure AD!
  http://blogs.technet.com/b/ad/archive/2014/09/03/50-saas-apps-now-support-federation-with-azure-ad.aspx

ブログ本文の本筋はたくさんのSaaSアプリケーションがAzure ADとのフェデレーションに対応したよ、ということなんですが下の方にちょろっとSP Initiated対応!と書いてあります。
これでようやくアプリケーションポータルを経由しなくてもSaaSアプリを使うことが出来ます。

と、言うことで試してみます。
と言っても設定はこれまでと何ら変わりません。今回もGoogle Appsを使います。

①Azure ADの管理コンソールからGoogle Appsを追加し、構成を行います。

 まずはGoogle Appsのドメインを指定します。

 Google Appsに設定する情報が出てくるので、証明書のダウンロードします。


②Google Appsのセキュリティ設定からシングルサインオン設定を行います。
 先ほどダウンロードした証明書のアップロード、各種URLの設定を行います。
 この時、「ドメイン固有の発行元を使用」にチェックを入れておくことを忘れないようにしてください。(前回はこれを入れていなかったからダメだっただけかも知れません。。)

③Azure ADのコンソールでGoogle Appsを使うユーザを追加、選択します。
 ※アプリケーションの構成でプロビジョニングを有効にしておく必要があります。
 Google Appsと同じドメインをAzure ADにも追加し、対象のドメインにユーザを作り、割り当てを行います。


④Google AppsへアクセスするとAzure ADのサインイン画面へリダイレクトされるので、先ほど追加したユーザでサインインします。


すると、無事にGoogle Apps(今回はGmail)が利用できます。




同じようなやり方でカスタムアプリや他のサービスも使えると思いますので、エンタープライズにおける利活用の選択肢がだいぶ拡がったと思います。


2014年8月1日金曜日

Azure ADのSAML対応(IdP編)

## 本POST時点ではIdP-Initiated SSOしか対応していなかったAzure ADですが、現在はSP-Initiated SSOにも対応しています。詳細は続編で解説しています。

Azure Active DirectoryのIdentity Providerとしての機能について、先日の.NETラボ勉強会で話をしましたが、そういえば説明してなかったなぁ、、と思うのがSAMLの対応状況です。

当日の勉強会資料はこちら
 


実は、現状ではAzure ADをSAML IdPとして使う際はIdP起動(IdP Initiated)のユースケースしか対応していません。

つまり、例えばGoogle AppsのようなサービスとのID連携が出来るようになったと言っても、これまで@ITなどで紹介してきた様に、
①サービス(SP)へアクセス
②AzureAD(IdP)へリダイレクト
③認証後、サービスへ戻って利用開始
という流れではサービス利用が出来ない、ということです。

参考)クラウド・サービスと社内システムとのID連携
  第4回 Google AppsとのID基盤連携を実現する
  http://www.atmarkit.co.jp/ait/articles/1301/16/news122.html



実際にGoogle AppsをAzure ADで認証するように構成して、https://mail.google.com/a/<テナントドメイン>へアクセスすると以下のようなエラーが発生します。


Azure ADのアプリケーションアクセス権限はもちろん割り当てているのですが、何とも分かりにくいエラーが出ます。




通信をトレースしてみると、以下のような流れになっています。


①サービスへアクセス
 GET https://mail.google.com/a/<テナントドメイン>/ HTTP/1.1
 ⇒HTTP 302
  Azure ADへリダイレクト

②Azure ADへの認証要求
 GET https://login.windows.net/25461215-0c1f-4dc2-bffc-63e6e6f3f759/saml2?SAMLRequest=xxx&RelayState: https://www.google.com/a/<テナントドメイン>/ServiceLogin?service=mail&passive=true&rm=false&continue=https%3A%2F%2Fmail.google.com%2Fa%2F<テナントドメイン>%2F&ss=1&ltmpl=default&ltmplcache=2&emr=1 HTTP/1.1

 実際のSAML Requestは以下の通り
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    ID="eafkldjajjdlncljdmnihogjokolljjfdooaboee"
                    Version="2.0"
                    IssueInstant="2014-07-31T14:34:01Z"
                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                    ProviderName="google.com"
                    IsPassive="false"
                    AssertionConsumerServiceURL="https://www.google.com/a/domain/acs"
                    >
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">google.com</saml:Issuer>
    <samlp:NameIDPolicy AllowCreate="true"
                        Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
                        />
</samlp:AuthnRequest>


 ⇒HTTP 302
  Azure ADの認証サービスへリダイレクト(ws-federationでID連携)

③login.microsoftonline.comへ認証要求
 GET https://login.microsoftonline.com/login.srf?wa=wsignin1.0&wreply=https%3a%2f%2flogin.windows.net%2f<テナントID>%2fwsfedisvacs&wp=MBI_FED_SSL&wctx=xxx HTTP/1.1

 ⇒ログイン画面表示

④ID/パスワードでログイン
 POST https://login.microsoftonline.com/ppsecure/post.srf?wa=wsignin1.0&wreply=https%3a%2f%2flogin.windows.net%2f<テナントID>%2fwsfedisvacs&wp=MBI_FED_SSL&wctx=xxx HTTP/1.1

⑤SAMLトークンを受け取り、Azure ADへPOST(ws-federationプロトコル)
 POST https://login.windows.net/<テナントID>/wsfedisvacs HTTP/1.1

 ⇒HTTP 400 Bad Request
  エラー!!先ほどの画面が表示される。



なかなか一筋縄ではいきません。
現状の解としてはアプリケーション・パネル(https://myapps.microsoft.com)からアプリケーションを立ち上げてIdP-InitiatedでID連携をすることとなります。

アプリケーション・パネル




ここからアプリケーション(Google Apps)を選択すると同じくSAMLを使ったID連携が行われて、サービスへログインできます。



このパターンの連携の流れは以下の通りです。

①アプリケーション・アイコンをクリック
 GET https://account.activedirectory.windowsazure.com/applications/redirecttofederatedapplication.aspx?Operation=SignIn&applicationId=<アプリケーションID>&ApplicationConstName=googleapps&SingleSignOnType=Federated&ApplicationDisplayName=Google+Apps HTTP/1.1

②SAML認証要求を発行
 GET https://login.windows.net/<テナントID>/saml2?SAMLRequest=xxxx&RelayState=https%3a%2f%2fwww.google.com%2fa%2facs%2fServiceLogin%3fservice%3dmail%26passive%3dtrue%26rm%3dfalse%26continue%3dhttps%253A%252F%252Fmail.google.com%252Fa%252Facs%252F%26ss%3d1%26ltmpl%3ddefault%26ltmplcache%3d2 HTTP/1.1

 この時のSAMLリクエストは以下の通り
<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                    ID="ide478f3cb10e54fd2882a3c68d24cd34a"
                    Version="2.0"
                    IssueInstant="2014-07-31T15:07:18.210Z"
                    IsPassive="false"
                    AssertionConsumerServiceURL="https://www.google.com/a/domain/acs"
                    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    >
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://google.com</Issuer>
    <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" />
</samlp:AuthnRequest>


③login.microsoftonline.comへ認証要求(シングルサインオン)
 GET https://login.microsoftonline.com/login.srf?wa=wsignin1.0&wreply=https%3a%2f%2flogin.windows.net%2f<テナントID>>%2fwsfedisvacs&wp=MBI_FED_SSL&wctx=xxx HTTP/1.1


④SAMLトークンをAzure ADへPOST(ws-federationプロトコル)
 POST https://login.windows.net/<テナントID>/wsfedisvacs HTTP/1.1


⑤SAMLトークンを発行し、Google AppsのACS(SP)へPOST
 POST https://www.google.com/a/<ドメイン>/acs HTTP/1.1

 POSTするSAML Responseは以下の通り
<samlp:Response ID="_cfa4d9a3-07f2-43b3-8721-ec009a314a42"
                Version="2.0"
                IssueInstant="2014-07-31T15:20:21.298Z"
                Destination="https://www.google.com/a/domain/acs"
                InResponseTo="ide478f3cb10e54fd2882a3c68d24cd34a"
                xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                >
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.windows.net/tenant/</Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <ds:Reference URI="#_cfa4d9a3-07f2-43b3-8721-ec009a314a42">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <ds:DigestValue>vldBy5BDCPN1SosH0pbBECXLspqjexOKf/CzGfvwhhA=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>SlEnVqcu--snip--cPDdkxuJMmg==</ds:SignatureValue>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
                <ds:X509Certificate>MIIDPjC--snip--Lg4rOBcXWLAIarZ</ds:X509Certificate>
            </ds:X509Data>
        </KeyInfo>
    </ds:Signature>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
    </samlp:Status>
    <Assertion ID="_28c961d7-b93e-4c21-88d9-62977d2ce849"
               IssueInstant="2014-07-31T15:20:21.298Z"
               Version="2.0"
               xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
               >
        <Issuer>https://sts.windows.net/tenant/</Issuer>
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
                <ds:Reference URI="#_28c961d7-b93e-4c21-88d9-62977d2ce849">
                    <ds:Transforms>
                        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                    <ds:DigestValue>swSVM5OvOHWnGp105KYZbMer4xuiJ0O9knGGBP4g/Us=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>V2Sbe7Ww--snip--okg==</ds:SignatureValue>
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>MIID--snip--arZ</ds:X509Certificate>
                </ds:X509Data>
            </KeyInfo>
        </ds:Signature>
        <Subject>
            <NameID>ieyasut@domain</NameID>
            <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <SubjectConfirmationData InResponseTo="ide478f3cb10e54fd2882a3c68d24cd34a"
NotOnOrAfter="2014-07-31T15:25:21.298Z"
Recipient="https://www.google.com/a/domain/acs"
/>
            </SubjectConfirmation>
        </Subject>
        <Conditions NotBefore="2014-07-31T15:20:21.005Z"
                    NotOnOrAfter="2014-07-31T16:30:21.005Z"
                    >
            <AudienceRestriction>
                <Audience>http://google.com</Audience>
            </AudienceRestriction>
        </Conditions>
        <AttributeStatement>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
                <AttributeValue>ieyasu</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
                <AttributeValue>tokugawa</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
                <AttributeValue>ieyasut@domain</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
                <AttributeValue>tenant</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
                <AttributeValue>4ce14587-d409-420e-82a2-7957867c6d20</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
                <AttributeValue>https://sts.windows.net/tenant/</AttributeValue>
            </Attribute>
        </AttributeStatement>
        <AuthnStatement AuthnInstant="2014-07-31T15:15:13.000Z"
                        SessionIndex="_28c961d7-b93e-4c21-88d9-62977d2ce849"
                        >
            <AuthnContext>
                <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
            </AuthnContext>
        </AuthnStatement>
    </Assertion>
</samlp:Response>



⑥Google Appsへのログイン処理(シングルサインオン)
 GET https://www.google.com/accounts/ContinueSignIn?sarp=1&continue=https%3A%2F%2Fmail.google.com%2Fa%2Facs%2F&plt=xxx&scc=0&service=mail HTTP/1.1

 ⇒Gmail画面の表示



いかがでしょうか?
単純にSAMLプロトコルに対応した、と言ってもどこまで対応しているかを知っておかないと利用イメージが違う、、という話になりかねないので、しっかりと押さえておかないといけませんね。

2014年6月17日火曜日

[告知]登壇予定(Office365、AAD、Identity)

最近はblogの更新もままならないほど忙しい日々なんですが、そんな中2本ほどイベントでお話をさせていただきます。いずれもAzure AD/Office365関係のアイデンティティ管理・フェデレーションの話の予定です。


■6/21(土)@大阪
SQL Worldさん
http://sqlworld.org/event/20140621/

タイムテーブルはこんな感じです。
時間内容スピーカー
13:05 -開場 
13:15 -ご挨拶 
20分 程度O365 概要(仮)SQLWorld 遥佐保
50分 程度O365 SharePointSQLWorld リシュ ジミー
20分 程度PowerBI + O365 の紹介SQLWorld お だ
10分 程度おやつタイム 
50分 程度運用を見据えた失敗しないOffice365導入(仮)Office365 MVP 渡辺元気 さん
50分 程度Office365とアイデンティティ(仮)FIM MVP 富士榮尚寛 さん


Office365、というかAADの話(ID管理、ID連携)をGraphAPIとかフェデレーションの仕組みの話とかをさせていただく予定です。


■6/28(土)@東京
.NETラボさん
http://www.dotnetlab.net/dnn/2014/05/net%E3%83%A9%E3%83%9C-%E5%8B%89%E5%BC%B7%E4%BC%9A-2014%E5%B9%B46%E6%9C%88-2/


こちらのタイムテーブルはこんな感じ。
■タイムテーブル
13:00 開場
13:15-13:30 「.NETラボ紹介」(.NETラボ スタッフ)
13:30-14:00「認証系を勉強する1日を企画したわけ」(Microsoft MVP for Client App Dev 高尾 哲朗)
14:00 – 17:00 「Office365の認証回りの仕様の移り変わりと運用上の苦労話」(Microsoft MVP for Office365 渡辺 元気)
「ADFS+Office365によるセキュリティ強化 デバイス認証、多要素認証編」(Microsoft MVP for Directory Services 国井 傑)
「AADとIdentity管理」(Microsoft MVP for Forefront Identity Manager 富士榮 尚寛)
Microsoft エバンジェリスト 安納さん(調整中)
17:00-17:30 「ライトニングトーク&ディスカッションタイム」
17:30 「グリーティングアワー」
18:00 終了


まぁ、似たような話をします。
ちょっと開発寄りな話になるかも知れません。


資料が全然できていないので、頑張って作ろうと思いますので、お時間のある方は是非・・・

2014年6月14日土曜日

[AAD/Office365]AAD Sync Betaを試す

しばらく時間が経ってしまいましたが、5月末に現在のディレクトリ同期ツール(DirSync)の後継となるAzure Active Directory Sync(AADSync)のベータ版がConnectサイトに公開されました。

 ダウンロードサイト(要登録)
 https://connect.microsoft.com/site433/Downloads/DownloadDetails.aspx?DownloadID=53361

 関連ポスト:
 [AAD/Office365]AAD Sync(次世代ディレクトリ同期)でクラウドのパスワードをオンプレミスへ
 http://idmlab.eidentity.jp/2014/04/aadoffice365aad-dync.html


基本は現在のディレクトリ同期と同様にForefront Identity Manager 2010 R2(FIM)ベースですが、より簡単に同期ルールを設定できるようなツールも付属しています。
これでディレクトリ同期ツールの手軽さとFIMの柔軟さの両方の良いところを活かすことが出来るようになります。
また同時にかねてからの課題であったマルチフォレスト環境への対応や.localドメインなどの課題へも対応できるようになっています。

今回は簡単にインストール~同期をした結果を載せてみます。


まず、注意事項ですが日本語環境ではBeta版のインストールは出来ませんので、英語環境にしてください。(OSインストールは日本語でも構いませんが、言語の追加で英語を追加し、表示言語を英語にした状態でインストールする必要があります)

ちなみに、当然のことながら事前にAzure AD上にディレクトリ同期を有効にしておく必要があります。

では始めます。

■インストール
モジュールをダウンロードして実行するとモジュールの展開・インストールが行われて自動的に設定が開始されます。

まずはAADへの接続情報の入力です。ここで入力するユーザはテナントの全体管理者の権限を持っている必要があります。


続いてオンプレミスのADDSの情報です。注目すべきはAdd Forestボタンです。
ここで複数のフォレストの情報を登録することでマルチフォレスト環境でもディレクトリ同期が出来ます。


設定したフォレスト情報が表示されているのがわかります。


次に2つの設定を行います。

一つ目はAcount Joinです。
これは複数のフォレストを同期する場合にアカウントを一意に識別してあげる必要があるのですが、その際に使用する属性を選択します。今回はシングルフォレスト構成なので、「My users are only represented once across all forests」を選択します。

二つ目はIdentity federationです。
AzureADとフェデレーションを行う場合にどの属性を使ってアカウントを紐づけるか?という設定です。AzureAD側ではImmutableIdという属性を使います。
これまでのディレクトリ同期ではobjectSidをBase64エンコードした値を使っていましたので、ShibbolethなどAD FS以外のSAML2.0 Identity Providerと接続する際は結構面倒だったのですが、今回からAAD側と紐づけをするための属性を自分で選択できるようになりました。

今回はUserPrincipalNameを選んでいます。


これまで通りHybrid環境のExchangeがある場合の設定もできます。


ここまで来たらもうすぐです。

完了です。その場で同期するならチェックしたままでFinishをクリックします。

とりあえず初期同期が走ります。

何の設定もしていないので、AADSyncを実行するユーザが同期されています。

ついでにグループも同期されています。これもゴミグループですね。。。



■同期ルール設定
これまではサポート外になるのを承知でmiisclientを使って同期ルールを編集することはできましたが、今回からは公式に同期ルールを編集するための簡易ツールがついてきます。

Synchronization Rule Editorが追加される。Synchronization Serviceは従来のmiisclient。


インバウンドとアウトバウンドの同期ルールが一覧で表示されるので、必要なモノを選択してEditをクリックすると編集できます。

ちなみにアウトバウンドはこんな感じ。AADへ連絡先、グループ、ユーザを同期するための設定が並んでいます。


試しにアウトバウンドのルールの編集をしてみます。

同期スコープも編集できます。これで特定のグループのユーザだけ同期する、なんていうことも簡単にできます。

このあたりがAADとオンプレミスのアカウントの紐づけです。どの属性で紐づけるかを選択できるので、例えばオンプレミスが.localドメインだった場合でもメールアドレスなどの属性を使って紐づけることが出来るようになります。

属性の接続など変わったことも出来ます。


ちなみに従来のmiisclientもSynchronization Serviceを開くと使えます。

ちなみにバージョン情報を見てもFIMの面影は消し去られています。。。


先日のOffice365の新機能発表でAzure AD Premiumの有償オプションだった多要素認証についてもMFA for Office365という形でサブスクライバへ無償提供されることが発表されていますし、このようにFIMを使わなくてもかなり柔軟にディレクトリ同期が出来るようになってきている、ますます簡単で便利な環境が提供されてきているので今後の展開が非常に楽しみです。

2014年5月21日水曜日

[AAD/ASP.NET] (続)OpenID Connectを使ってAADでログオンする~response_mode=fragment編

先日のポストの続きです。

前回はOWIN Security MiddlewareのOpenID Connectを使ってAzure Active Directory(AAD)でのログオンを行いました。
今回も基本的にやることは同じなのですが、OWINのOpenID Connectのresponse_modeの初期値がform_postなので、一般的なOpenID ConnectをサポートしたIdentity Providerへの流用の可能性を考えるために、Implicitフローで使われるfragmentを使ってid_tokenを受け渡す場合の工夫について試してみます。
※尚、現状AADではImplicitフローをサポートしているという表明があるわけではないので、今回紹介するのはあくまでImplicitもどきです。


■処理の流れとAADの場合
まず、OpenID ConnectにおけるImplicit Clientではどのような流れでid_tokenが発行されるのか?、AADではどうなるのか?についてみておきたいと思います。
 参考)OpenID Connect Implicit Client Implementer's Guide 1.0 - draft 15の日本語訳
    http://openid-foundation-japan.github.io/openid-connect-implicit-1_0.ja.html

大まかな流れは、以下のようになっています。

①Client は必要なリクエストパラメータを含んだ Authentication Request を構築する.
②Client は Authorization Server にリクエストを送信する.
③Authorization Server は End-User を認証する.
④Authorization Server は End-User の Consent/Authorization を取得する.
⑤Authorization Server は End-User を ID Token, およびもし要求されていれば Access Token とともに, Client に戻す.
⑥Client はそれらのトークンを検証し, End-User の Subject Identifier を取得する.


具体的には以下のような通信が行われます。

①~②クライアントからのAuthorizationリクエスト
https://server.example.com/authorize?
    response_type=id_token%20token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj


response_typeにid_tokenおよびtokenを付けて要求を投げる必要がある(REQUIRED)、というのが仕様です。
しかし、現状でAADはresponse_typeにtokenをサポートしていないので、id_tokenだけを要求することにします。また、前述の通り、AADではresponse_modeの初期値がform_postなので、Implicit(もどき)の場合はresponse_mode=fragmentをつける必要があります。

結果、以下のようなリクエストになります。
https://login.windows.net/{tenantid}/oauth2/authorize?
    response_type=id_token
    &response_mode=fragment
    &client_id=xxxxx
    &redirect_uri=https%3a%2f%2flocalhost%3a44307%2fAccount%2fFragment%2f
    &scope=openid+profile
    &state=yyyyy
    &nonce=zzzzz



③~④End-Userの認証、同意取得
この部分は仕様のスコープ外なので手段は問いません。
AADではws-federationを使ってhttps://login.microsoftonline.comへ認証要求を投げ、ユーザ認証を行います。
https://login.microsoftonline.com/login.srf?
    wa=wsignin1.0
    &wtrealm=https%3a%2f%2flogin.windows.net%2f
    &wreply=https%3a%2f%2flogin.windows.net%2f{tenantid}%2fwsfederation
    &wctx=xxxx
    &wp=MBI_FED_SSL
    &id=


認証が成功するとhttps://login.windows.net/{tenantid}/wsfederationに対してSAMLトークンがPOSTされ、認証結果およびユーザ情報が渡されます。


⑤id_tokenをクライアントへ返す
HTTP302でredirect_uriへ戻します。その際、フラグメント(#)にid_tokenなど要求されたトークンを付加します。
HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    access_token=SlAV32hkKG
    &token_type=bearer
    &id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
    &expires_in=3600
    &state=af0ifjsldkj


AADの場合は、先ほどのリクエストでtokenを要求できませんでしたので、id_tokenのみが返ってきます。
HTTP/1.1 302 Found
  Location: https://localhost:44307/Account/Fragment/#
    id_token=eyJ0....
    &state=yyyyy
    &session_state=zzzzz



⑥返ってきたid_tokenを検証する
id_tokenがフラグメントで返ってきますので、UserAgent(ブラウザ等)上でパラメータを解析してクライアントへ送ってあげる必要があります。通常はJavaScriptでlocation.hashを解析してクライアントへid_tokenなどをPOSTしてあげます。
今回もredirect_uriに指定したページ(https://localhost:44307/Account/Fragment/)へのGETリクエストすると以下のようなJavaScriptを含むHTMLを返すようにしています。(テストなのでベタ書きしています)
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title></title>
</head>
<body>
    <form method="post" name="autopost" action="https://localhost:44307/">
        <script type="text/javascript">
            var params = location.hash.substring(1).split('&');
            var id_token = params[0].substring(9);
            var state = params[1].substring(6);
            var session_state = params[2].substring(14);

            document.write("<input type=hidden name=id_token value=");
            document.write(id_token);
            document.write(" />");
            document.write("<input type=hidden name=state value=");
            document.write(state);
            document.write(" />");
            document.write("<input type=hidden name=session_state value=");
            document.write(session_state);
            document.write(" />");
        </script>
        <input type="submit" value="Submit" />
    </form>
    <script language="javascript">window.setTimeout('document.forms[0].submit()', 0);</script>
</body>
</html>




結果、フラグメントでわたってきたid_tokenがOWINのOpenID Connect Middlewareが動いているASP.NETアプリケーション(https://localhost:44307)へPOSTされ、自動的にトークン検証~ユーザ情報の取り出しを行ってくれます。


ここまでのフローをざっとシーケンスにしたものが以下の図です。



■ASP.NET/OWINでの実装
デフォルトのASP.NET/OWIN Middlewareではフラグメントでわたってきたid_tokenをUserAgent側で解析してPOSTする部分が用意されていないので、その部分だけは作ってあげる必要があります。
具体的にはViewを一つ用意して、そのエンドポイントに対するGETがあった場合に先のJavaScriptを含むHTMLを返すようにします。

以下の手順で実装しました。

ソリューション・エクスプローラからAccount Controllerへ新規MVC5 Viewを追加します。先のシーケンスの中にも出てきたように、今回はエンドポイントの名前を「Fragment」としています。



新規作成されたfragment.chtmlに先のJavaScriptを含むHTMLを記載します。



次に、Account Controllerにアクションを定義します。AccountController.csに以下のコードを追記します。
[AllowAnonymous]
public ActionResult Fragment()
{
    return View();
}



また、OWINの認証設定部分(Startup.Auth.cs)に以下の設定を入れます。
・response_type:id_token
・response_mode:fragmentを指定
・redirect_uri:先に追加したView(Fragment)のエンドポイントを指定

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions()
    {
        Client_Id = "xxxxx",
        Authority = "https://login.windows.net/{tenant}.onmicrosoft.com",
        Response_Type = "id_token",
        Response_Mode = "fragment",
        Redirect_Uri = "https://localhost:44307/Account/Fragment/",
        Description = new Microsoft.Owin.Security.AuthenticationDescription()
        {
            Caption = "Azure Active Directory",
            AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType
        }
    });



これで実行すると前回と同じような動きに見えますが、裏側ではImplicit(もどき)でid_tokenが受け渡されます。