OAuth と SAML を使用して Windows Live と SharePoint 2010 のフェデレーションを実現する便利な方法
原文の記事の投稿日: 2012 年 3 月 1 日 (木曜日)
これまで多くの方々が SharePoint と Windows Live のフェデレーションについて私に話しかけてきました。これは、表面上、とても良いアイデアのように思われます。Windows Live には数百万ものユーザーがいます。各ユーザーは自分の電子メール アドレスを使用してログインします。電子メール アドレスは、私たちが ID クレームとして何度も使用するものです。ID クレームは、大きくてスケーラブルなサービスであり、私たちには、ID クレームを直接的にまたは ACS (Access Control Service) 経由で処理するさまざまな方法があります。しかし、SharePoint で ID クレームを使用することに関してどうして私は気難しくなるのでしょう。これを以前に試したことがある方は知っています。Windows Live とフェデレーションを行うときにクレームとしてユーザーの電子メール アドレスが返されないということを。返されるのは PUID と呼ばれる特別な Windows Live ID のみです。私が知る限りでは、"PUID" は "実質的に GUID" の略のはずです。なぜなら、これはまさに想像のとおりのものであり、非常に便利なものだからです。
たとえば、Windows Live とフェデレーションを行う場合、ユーザーをサイトにどのように追加しますか。これを行うには、ユーザーの PUID を取得して、PUID を SharePoint グループまたはアクセス許可レベルに追加する必要があります。あなたは、自分の PUID を把握しているユーザーを本当に知っていますか (もし知っていれば、空き時間に何をするかを考えたほうがよいでしょう)。魔法でも使ったかのように自分の PUID を偶然に知ることができても、異なるサイト コレクションへの権限をユーザーに付与するのに、それが役に立つと思いますか。他の誰かが PUID の羅列 (または場合によってはユーザー選択ウィンドウ) からあなたを選択できると本当に思いますか。もちろん、そのようなことはできません。これに対する私の欲求不満は募るばかりです。
私は、ACS を使ったより空想的な解決策にここで挑戦することができるかもしれないと考えました。ACS は、Windows Live、Google、Yahoo 、Facebook など、いくつかの ID プロバイダーに、すぐに使用できるフックを提供するという点で非常に優れた機能です。Facebook では、少し魔法もちりばめられていますが、実際に OAuth を使用して認証が行われ、一連の SAML クレームが返されています。これはすばらしいことです。しかし、なぜ、Windows Live でもこれと同じことが行われないのでしょうか。Windows Live では OAuth がサポートされるようになりました。このため、価値のある何かが実現する機会がついに訪れたように思われます。しかし、このように希望しても、ACS の方たちがここに来て助けてくれることはありませんでした。この序文の要点はここにあります。最終的に、私自身がここに書くことを決定しました。これがこの投稿のポイントです。
では、なぜ、私たちは OAuth に関心があるのでしょうか。Windows Live と直接フェデレーションを行うときに取得する PUID とは対照的に、Windows Live の OAuth サポートでは、ユーザーに関するより多くの情報を取得できます。たとえば、電子メール アドレスです。このため、ここでの攻撃計画は基本的に次のようになります。
- Windows Identity Foundation (WIF) を使用して、カスタム ID プロバイダーを記述します。
- ユーザーが STS にリダイレクトされたときに、そのユーザーがまだ認証されていない場合、ユーザーをさらに Windows Live にリダイレクトします。これを行うには、Windows Live を使用する "アプリケーション" を作成する必要があります。その詳細については、後で説明します。
- ユーザーが認証されると、ユーザーはカスタム STS に戻ります。ユーザーが戻ったときのクエリ文字列にはログイン トークンが含まれます。このログイン トークンをアクセス トークンとして交換できます。
- 次に、STS はログイン コードを使用し、Windows Live に対してアクセス トークンを求める別の要求を行います。
- STS はアクセス トークンを取得すると、そのアクセス トークンを使用し、Windows Live に対して、ユーザーに関するいくつかの基本情報を求める最後の要求を行います (何を取得するかについては後で説明します)。
- Windows Live からユーザー情報を受け取ると、カスタム STS を使用してユーザー用の一連の SAML クレームを作成し、それにユーザー情報データを入力します。その後、最初に認証を要求してきたアプリケーションにリダイレクトして、そのアプリケーションが SAML トークンを使用して実行する必要があった処理を行うことができるようにします。この特定のケースでは、標準の ASP.NET アプリケーションおよび SharePoint 2010 Web アプリケーションを使用して STS をテストしました。
この投稿にすべてのソース コードを添付しましたが、まだいくつかの構成を行う必要があります。また、アプリケーション ID および Windows Live から取得したシークレットを使用してアプリケーションを再コンパイルする必要があります。ただし、このソース コードのコピーと貼り付けを行う以外に、実行のために記述する必要のあるコードはありません。ここで、このアプリケーションを使用するのに必要なすべての作業について説明します。
トークン署名証明書を作成する
SAML トークンへの署名に使用する証明書を作成する必要があります。証明書用の秘密キーがあることを確認する必要がある以外に、証明書への署名に使用する証明書に関して特別なことはありません。私の場合は、証明書サービスを私のドメインにインストールしていたので、IIS マネージャーを開いて、ドメイン証明書を作成するためのオプションを選択しただけでした。私はウィザードに従って、秘密キーを使用して新しい証明書をあっという間に完成しました。このプロジェクトでは、livevbtoys という証明書を作成しました。
次のセクションで説明するように、要求が最初に STS に入って来たときのユーザーは匿名ユーザーです。その証明書を使用して SAML トークンに署名するには、IIS プロセスに、その証明書の秘密キーへのアクセス権を付与する必要があります。匿名要求が入って来たときの IIS プロセス ID はネットワーク サービスです。それにキーへのアクセス権を与えるには、以下の処理を行う必要があります。
- MMC を開始します。
- 証明書スナップインを追加します。ローカル コンピューターのコンピューター ストアを選択します。
- 個人証明書ストアを開き、SAML トークンへの署名のために作成した証明書を見つけます。上記の説明のとおりに証明書が作成されている場合、既定では、この場所に証明書が存在します。他の方法を使用して証明書が作成されている場合は、証明書をこのストアに追加することが必要になる場合があります。
- 証明書を右クリックし、[秘密キーの管理] オプションを選択します。
- キーへの権限を持つユーザーのリストで、ネットワーク サービスを追加し、そのネットワーク サービスにキーへの読み取り権限を与えます。
この処理を正しく行っていない場合、アプリケーションの実行を試みたときに、"キーセットが存在しない" ことを示すエラーが表示される場合があります。これは、IIS プロセスが秘密キーに対する十分な権限を持っていなかったために、IIS プロセスは秘密キーを使用して SAML トークンに署名できなかったことを示します。
アプリケーションおよび必要なアセンブリをインストールする
ここでアプリケーションをインストールすることは、単に、ASP.NET アプリケーションを IIS に作成し、いくつかのコピーを行って、最新バージョンの WIF がインストールされていることを確認することを意味します。構成が完了し、当然ながら 1 台のサーバーで作業を行っていると、サーバーをさらに追加してフォールト トレラント ソリューションを実現したくなりますが、ここでは、1 台のサーバーに対して必要とされる構成について説明します。
ここでは、ASP.NET アプリケーションを IIS に作成する方法については説明しません。これを行うには、Visual Studio、IIS マネージャーなどを使用できます。
メモ: 単に、ここに提供されているコードを使用して Visual Studio でプロジェクトを開いた場合、ホストまたはサイトが存在しないことを示すメッセージが表示されます。これは、私のサーバーの名前が使用されているためです。これを最も簡単に解決する方法は、WindowsLiveOauthSts.sln ファイルを手動で編集し、そのファイルの中にある https の値を、環境に実際に存在する値に変更することです。
アプリケーションを実際に作成した後、いくつかの作業を行う必要があります。
- PassiveSTS.aspx を、STS Web サイト用の IIS マネージャーに既定のドキュメントとして追加します。
- 匿名認証用の認証の種類を除いて、すべての認証の種類を無効にするように、IIS 内のアプリケーションの認証設定を変更します。
- STS は、SSL 上で実行される必要があります。したがって、STS 用の適切な証明書を取得する必要があるとともに、カスタム STS アプリケーションを使用する IIS 仮想サーバー上でバインドが更新されるようにする必要があります。
- 証明書利用者の web.config の trustedIssuers セクション内にある add 要素の thumbprint 属性に、トークン署名証明書の拇印を設定していることを確認します (テストで SharePoint を "使用しない" 場合)。Visual Studio で STS 参照の追加ウィザードを使用する場合、この処理は自動的に行われます。
IIS で必要とされる構成はこれだけです。
カスタム STS プロジェクトの更新とビルドを行う
添付の zip ファイルには、WindowsLiveOauthSts と呼ばれる Visual Studio 2010 プロジェクトが含まれます。前述のとおりに、IIS が構成され、WindowsLiveOauthSts.sln ファイルの更新が完了すると、Visual Studio でプロジェクトを正常に開くことができます。初めに行う必要がある作業の 1 つは、PassiveSTS.aspx.cs クラス内にある CLIENT_ID および CLIENT_SECRET 定数を更新することです。これらの定数は、新しい Windows Live アプリケーションを作成するときに取得されます。このアプリケーションの詳細な作成手順について、ここでは説明しません (Windows Live の専門家たちに聞いてください) が、Windows Live アプリケーションを作成できる便利な場所 (https://manage.dev.live.com/Applications/Index?wa=wsignin1.0 (英語)) を紹介します。また、アプリケーションを作成するときは、リダイレクト ドメインを、カスタム STS がホストされる場所 (https://myserver.foo.com など) に必ず設定してください。
ID とシークレットは準備されています。ここで、アプリケーションで更新する必要があるものについて説明します。
- PassiveSTS.aspx.cs 内にある CLIENT_ID および CLIENT_SECRET 定数を更新します。
- web.config ファイルの appSettings セクション内にある SigningCertificateName を更新します。IssuerName 設定を変更する必要はありませんが、必要があれば当然これも変更できます。
- STS プロジェクト内にある FederationMetadata.xml ドキュメント用のトークン署名証明書を更新します。使用する証明書の選択が完了すると、この投稿に含まれる test.exe アプリケーションを使用して証明書の文字列値を取得できます。これをコピーして、federationmetadata.xml 内にある 2 つの X509Certificate 要素値を置き換える必要があります。
ここで、もう 1 つ指摘しておくことがあります。CustomSecurityTokenService.cs ファイルでは、enableAppliesToValidation という変数を true に設定し、このカスタム STS を使用できる URL のリストを指定できます。私の場合、これをまったく制限しないように選択しました。したがって、この変数は false になっています。カスタム STS の使用を整理する場合は、ここで変更する必要があります。これらの変更が完了すると、アプリケーションを再コンパイルできます。これで準備完了です。
さらにもう 1 つ注意することがあります。私はサンプルの ASP.NET アプリケーションも含めました。私はこれをビルドするときにこのアプリケーションを使用してテストを行いました。このアプリケーションは、LiveRP というプロジェクトに含まれます。このアプリケーションの詳細について、ここでは説明しません。テストする場合にこのようなアプリケーションもあるということを述べるだけにします。ただし、前述のとおりに、STS トークン署名証明書の拇印を変更することを覚えて置いてください。
SharePoint の構成
この時点ですべての構成が完了しており、それらの構成はカスタム STS で機能します。残っている唯一の作業は、新しい SPTrustedIdentityToken 発行者を SharePoint に作成し、その発行者を使用するように新しいまたは既存の Web アプリケーションを構成することです。SPTrustedIdentityTokenIssuer を構成するには、いくつかの注意事項があります。ここで、私が使用した PowerShell について説明します。
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\livevbtoys.cer")
New-SPTrustedRootAuthority -Name "SPS Live Token Signing Certificate" -Certificate $cert
$map = New-SPClaimTypeMapping -IncomingClaimType "https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
$map2 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/id" -IncomingClaimTypeDisplayName "WindowsLiveID" -SameAsIncoming
$map3 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/full_name" -IncomingClaimTypeDisplayName "FullName" -SameAsIncoming
$map4 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/first_name" -IncomingClaimTypeDisplayName "FirstName" -SameAsIncoming
$map5 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/last_name" -IncomingClaimTypeDisplayName "LastName" -SameAsIncoming
$map6 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/link" -IncomingClaimTypeDisplayName "Link" -SameAsIncoming
$map7 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/gender" -IncomingClaimTypeDisplayName "Gender" -SameAsIncoming
$map8 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/locale" -IncomingClaimTypeDisplayName "Locale" -SameAsIncoming
$map9 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/updated_time" -IncomingClaimTypeDisplayName "WindowsLiveLastUpdatedTime" -SameAsIncoming
$map10 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/account" -IncomingClaimTypeDisplayName "AccountName" -SameAsIncoming
$map11 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/accesstoken" -IncomingClaimTypeDisplayName "WindowsLiveAccessToken" -SameAsIncoming
$realm = "https://spslive.vbtoys.com/_trust/"
$ap = New-SPTrustedIdentityTokenIssuer -Name "SpsLive" -Description "Window Live oAuth Identity Provider for SAML" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map,$map2,$map3,$map4,$map5,$map6,$map7,$map8,$map9,$map10,$map11 -SignInUrl "https://spr200.vbtoys.com/WindowsLiveOauthSts/PassiveSTS.aspx" -IdentifierClaim "https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
いくつかの注意点について説明します。
- 前述のとおり、私はトークンに署名するための livevbtoys.cer という証明書を作成したので、この証明書を SPTrustedRootAuthority リストに追加して、トークン発行者に関連付けました。
- 私は、私のカスタム STS が返すすべてのクレームに対して要求のマップを作成しました。お分かりのとおり、これにより、Windows Live と直接フェデレーションしただけの場合に得られたものよりも "格段に多くの優れた" ものが得られます。もう 1 つ注意することがあります。私は、Windows Live から取得したアクセス トークンをクレームとしてここに含めました。これは Facebook では機能しますが、テストしていないので、Windows Live でそのアクセス トークンを再利用できるかどうか確信がありません。これは、おそらく、将来の投稿のトピックになるでしょう。
- $realm の値は極めて重要です。この値は Web アプリケーションのルート サイトを指す必要があります。また、この値に /_trust/ ディレクトリを含める必要があります。これが正しく行われていない場合、認証後に戻されたときに SharePoint から 500 個のエラーを受け取ります。
- トークン発行者を作成するときの –SignInUrl パラメーターは、私のカスタム STS の PassiveSTS.aspx ページへの絶対 URL です。
大体の説明はこれで終わりです。このセットアップが完了しても、すぐに使用できるユーザー選択ウィンドウとクレーム プロバイダーが使用されていると、ご想像のとおり、参照機能は得られません。Windows Live へのサインインに使用する電子メール アドレスを使用してユーザーに権限を付与します。この例は実際に拡張できます。また、私がブログ (https://blogs.msdn.com/b/sharepoint_jp/archive/2012/03/12/the-azure-custom-claim-provider-for-sharepoint-project-part-1.aspx) に書いた Azure クレーム プロバイダーを使用することもできます。つまり、この STS を使用すると、Windows Live との認証を行っていくつかの実際の SAML クレームを取得できます。その後、Azure のカスタム クレーム プロバイダー プロジェクトを使用して、認証されたユーザーを Azure ディレクトリ ストアおよびユーザー選択ウィンドウに追加し、それらのユーザーを選択することができるようになります。
以下の図がすべてを表しています。これは、SharePoint サイトに最初にヒットして Windows Live との認証を行う画面です。
最初にサインインするときに、あなたの情報をカスタム STS アプリケーションと共有しても良いかどうかを聞かれます。ここで心配することはありません。これは、OAuth アクセス許可の標準の出来事です。このときの画面を以下に示します。この画面には、私が STS の中で要求しているデータが表示されています。必要があれば、まったく異なるデータ セットを要求することができます。変更する必要があるものと方法については、Window Live OAuth の SDK を参照してください。
これを受け付けると、SharePoint にリダイレクトされます。この例では、私がブログ (https://blogs.technet.com/b/speschka/archive/2010/02/13/figuring-out-what-claims-you-have-in-sharepoint-2010.aspx (英語)) に書いた SharePoint クレーム Web パーツが使用されています。この画面では、OAuth を使用して Windows Live から私が取得したすべてのクレーム、つまり、私のカスタム STS のおかげで SAML クレームとして現在保持されているすべてのクレームを確認できるとともに、このプロジェクト用に作成した Windows Live 電子メール アドレスを使用して私がサインインしている事実を確認できます (右上のサインイン コントロールを参照)。
これはローカライズされたブログ投稿です。原文の記事は、「Finally A USEFUL Way to Federate With Windows Live and SharePoint 2010 Using OAuth and SAML」をご覧ください。