[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]] -[[戻る>ASP.NET Identity]] * 目次 [#i42bb417] #contents *概要 [#x3f02a0a] [[ASP.NET Identity]]は、以下の[[クレームベース認証]]のセキュアトークンサービス(STS)のEndpoint追加をサポートしている。 **プロトコル [#z3d3c75d] ***[[OAuth]] 2.0 [#w9606fd6] -OAuthAuthorizationServerProviderでは、[[OAuth]]のセキュアトークンサービス(STS)のEndpoint追加をサポートしており、~ これにより、Java、JavaScript、Perl、PHP、Python、Rubyなどの「非 .NET 環境」と認証処理を連携させることもできる。 -なお、[[OAuth]] 2.0は認可のプロトコルなので、認証の目的で使用する場合は[[セキュリティ>#c75e8910]]に注意が必要になる。 ***[[OpenID Connect]] [#cd0c97cc] [[OpenID Connect]]のセキュアトークンサービス(STS)のEndpoint追加は、現時点(2016年)では提供されていない。 -https://github.com/jchannon/katanaproject/tree/master/src/Microsoft.Owin.Security.OpenIdConnect -https://github.com/jchannon/katanaproject/tree/master/src/Microsoft.Owin.Security.OAuth **認証・認可サーバ [#h7b76293] ***準備 [#d240d6f2] +Visual Studio 2015 で、新規 ASP.NET Web アプリケーションを作成する。 +「新しい ASP.NET プロジェクト」ダイアログで、以下を選択する。 --テンプレート: [[ASP.NET MVC]] --認証の変更: 個別のユーザー アカウント +Visual Studio の「パッケージ マネージャー コンソール」で、以下のコマンドを実行する。 Install-Package Microsoft.AspNet.WebApi Install-Package Microsoft.AspNet.WebApi.Owin Install-Package Microsoft.AspNet.WebApi.Cors ***構成 [#x822a240] -[[ASP.NET MVC]]アプリケーションとして作成する。 -[[ASP.NET Identity]]を用いて、各 Web アプリのアカウント管理を行う。 -ユーザー情報へアクセスする処理は、カスタムのUserStoreクラスへ実装する。 -UserStoreクラスは、データベース(SQL Server, PostgreSQL, etc.)にユーザー情報を格納する。 **クライアント・アプリ開発 [#o40edf90] ***[[cURLコマンド]] [#nd05e06c] -HTTPClientなどからTokenエンドポイントにアクセスして連携するシナリオ。 -グラント種別 --「[[Resource Owner Password Credentialsグラント種別>#ka3a0c97]]」 --「[[Client Credentialsグラント種別>#h00dd765]]」 ***Webアプリケーション [#o67fc248] -「[[Authorization Codeグラント種別>#v9f92532]]」のシナリオを検証する。 -Webアプリケーションで、WebAPI(OAuthリソース)へのアクセスを認可。 -ここでは、クライアント・アプリを認証・認可サーバに同梱させてしまう。 ***JavaScript [#o67fc248] -「[[Implicitグラント種別>#kb8fee48]]」のシナリオを検証する。 -SPA(Browser+WebAPI)で、WebAPI(OAuthリソース)へのアクセスを認可。 -ここでは、クライアント・アプリを認証・認可サーバに同梱させてしまう。 * Tokenエンドポイントの検証手順 [#zd7b2804] -以下のシナリオの検証を行うことができる。 --「[[Resource Owner Password Credentialsグラント種別>#ka3a0c97]]」 --「[[Client Credentialsグラント種別>#h00dd765]]」 -以下を参考にして検証手順を作成した。 --[[OWIN OAuth 2.0 Authorization Server | The ASP.NET Site>#e91aecfc]] **エンドポイント一覧 [#xe03ec6c] **認証・認可サーバ開発 [#e784dfce] コードの提示はGithub登録まで待ってください。 **クライアント・アプリ開発 [#vdcf702a] ここの検証では、[[cURLコマンド]]を使用するため開発不要。 **認証連携の動作検証 [#jcf369d6] [[cURLコマンド]]を使用して認証連携の動作を検証する。 ***[[Resource Owner Password Credentialsグラント種別>OAuth#i2483bc0]] [#ka3a0c97] -処理の概要 --Tokenエンドポイントに対して以下のRequestを出すと、Bearer Tokenが返ってくる。 ---POST ---Content-Type: application/x-www-form-urlencoded; ---body:grant_type=password, username=ユーザ名, password=パスワード --Bearer Tokenをヘッダに指定してResources用のEndpointにアクセスするとResources情報を取得できる。 ---GET ---Authorization: Bearer XXXXXXXXXX ---Content-Type: application/json; charset=utf-8; -[[cURLコマンド]]~ Debug ProxyにFiddler等を使用すると尚良~ (其の際は、 --proxy オプションを指定する必要がある)。 --Bearer Tokenの取得 ---Request (cURLコマンド) >curl "http://localhost/OAuthBearerToken" -H "Content-Type: application/x-www-form-urlencoded;" -d "grant_type=password" -d "username=XXXXX" -d "password=YYYYY" ---Response (Body) {"access_token":"XXXXXXXXXX","token_type":"bearer","expires_in":nnnnn} --Bearer Tokenを使用したOAuthリソースへのアクセス ---Request (cURLコマンド) >curl "http://localhost/api/OAuthResourceApi/GetClaim" -H "Authorization: Bearer XXXXXXXXXX" -H "Content-Type: application/json; charset=utf-8;" ---Response (Body) {"id":"XXXXX","userName":"XXXXX","email":"XXXXX","phoneNumber":"XXXXX"} ***[[Client Credentialsグラント種別>OAuth#ka6e3a8f]] [#h00dd765] -処理の概要 --Tokenエンドポイントに対して以下のRequestを出すと、Bearer Tokenが返ってくる。 ---POST ---Content-Type: application/x-www-form-urlencoded; ---body:grant_type=client_credentials, client_id=XXXXXX, client_secret=YYYYYY --Bearer Tokenをヘッダに指定してResources用のEndpointにアクセスするとResources情報を取得できる。 ---GET ---Authorization: Bearer XXXXXXXXXX ---Content-Type: application/json; charset=utf-8; -[[cURLコマンド]]~ Debug ProxyにFiddler等を使用すると尚良~ (其の際は、 --proxy オプションを指定する必要がある)。 --Bearer Tokenの取得 ---Request (cURLコマンド) >curl "http://localhost/OAuthBearerToken" -H "Content-Type: application/x-www-form-urlencoded;" -d "grant_type=client_credentials" -d "client_id=XXXXXX" -d "client_secret=YYYYYY" ---Response (Body) {"access_token":"XXXXXXXXXX","token_type":"bearer","expires_in":nnnnn} --Bearer Tokenを使用したOAuthリソースへのアクセス ---Request (cURLコマンド) >curl "http://localhost/api/OAuthResourceApi/GetClaim" -H "Authorization: Bearer XXXXXXXXXX" -H "Content-Type: application/json; charset=utf-8;" ---Response (Body) {"id":"XXXXX","userName":"XXXXX","email":"XXXXX","phoneNumber":"XXXXX"} * 認可エンドポイントの検証手順 [#ua532943] -以下のシナリオの検証を行うことができる。 --「[[Authorization Codeグラント種別>#v9f92532]]」 --「[[Implicitグラント種別>#kb8fee48]]」 -以下を参考にして検証手順を作成した。 --[[OWIN OAuth 2.0 Authorization Server | The ASP.NET Site>#e91aecfc]] --[[その他 - Implicitグラント種別>#j1c1a778]] --ASP.NET Identityのプロジェクト・テンプレートを使用 > +[[ASP.NET SPA]]テンプレートの動作確認を行なった後、 +[[ASP.NET MVC]]テンプレートの差分を確認した上で、 +[[OAuth]]に必要な実装を抽出し、 +[[ASP.NET MVC]]テンプレートに[[OAuth]]のEndpointを追加する手順を書き出し、 +その手順の妥当性を以下の検証手順によって検証した。 **エンドポイント一覧 [#d1cbf5ad] **認証・認可サーバ開発 [#c21960e5] コードの提示はGithub登録まで待ってください。 **クライアント・アプリ [#we1f472c] コードの提示はGithub登録まで待ってください。 ***Webアプリケーション [#jfc73185] ***JavaScript [#b1043060] **認証連携の動作検証 [#a85aac65] ***[[Authorization Codeグラント種別>OAuth#y8bf613e]] [#v9f92532] -client_id --引継:OK --検証:OK -redirect_uri --引継:OK --検証:OK -scope --引継:OK --検証:自前 -state --引継:OK --検証:自前 ***[[Implicitグラント種別>OAuth#h347a7c6]] [#kb8fee48] *その他 [#g4d5acce] **ASP.NET IdentityでRFCに追加されている仕様 [#z90cfe4c] -「MUST (しなければならない)」 -「MUST NOT (してはならない)」 -「REQUIRED (必須である)」 以外の部分で、強制されている実装を朱書きに設定した。 ***[[Authorization Codeグラント種別>OAuth#y8bf613e]] [#a0c59c8d] -client_id --引継:OK --検証: ---クライアント認証は自前 ---&color(red){Endpoint間の一致は自動検証}; -redirect_uri --引継:OK --検証: ---client_idとの部分一致などは自前 ---Endpoint間の一致は自動検証 -scope --引継:OK --検証:自前 -state --引継:OK --検証:自前 ***[[Implicitグラント種別>OAuth#h347a7c6]] [#r8ad5c39] **Bearer Tokenを暗号化・復号化する秘密鍵 [#xcd8dac1] -認可サーバ(AuthorizationServer)とリソースサーバ(ResourceServer)が同じマシン上に無い場合、~ Bearer Tokenを暗号化・復号化する秘密鍵を双方のマシン間で一致させる必要がある。 -これには、以下のように、machinekeyを両方のweb.configファイルに追加する必要がある。 <system.web> <machineKey decryptionKey="Enter decryption Key here" validation="SHA1" validationKey="Enter validation Key here" /> </system.web> -machineKeyセクションの生成には、以下のツールが使えそう。 --garafu/MachineKeyGenerator:~ https://github.com/garafu/MachineKeyGenerator >This tool allows you to generate random keys for validation and encryption/decription of the view state. *参考 [#k32a6edf] -OAuthAuthorizationServerProvider クラス (Microsoft.Owin.Security.OAuth)~ https://msdn.microsoft.com/ja-jp/library/microsoft.owin.security.oauth.oauthauthorizationserverprovider.aspx **The ASP.NET Site [#e91aecfc] -OWIN OAuth 2.0 Authorization Server~ https://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server このコンテンツは以下の様な構成になっている。 ***Create an Authorization Server [#ub84ef28] -このAuthorization ServerはOAuthの4つのフローをサポートしている。 --Authorization Code Grant Client --Implicit Grant Client --Resource Owner Password Credentials Grant Client --Client Credentials Grant Client -サーバーの設定と実装 --OWIN Startup classでの設定 --OAuthAuthorizationServerProviderの実装 ---ValidateClientRedirectUri~ (Authorization Code, Implicitグラント種別) ---ValidateClientAuthentication~ (Resource Owner Password Credentials, Client Credentialsグラント種別) ---GrantResourceOwnerCredentials~ (Resource Owner Password Credentialsグラント種別) ---GrantClientCredetails~ (Client Credentialsグラント種別) --AuthorizeEndpointの実装~ (Authorization Code, Implicitグラント種別) ***Creating a Resource Server [#ld778043] アクセストークンによって保護されたResource ServerのEndpointを作成。 ***Create OAuth 2.0 Clients [#y247ad21] .NETクライアント・アプリからHTTPアクセスする際のライブラリとしては、[[DotNetOpenAuth.OAuth2>https://www.nuget.org/packages/DotNetOpenAuth.OAuth2.Client]]を使用している。 -Authorization Code Grant Client~ WebApplicationとして実装。 -Implicit Grant Client~ JavaScriptで実装。 -Resource Owner Password Credentials Grant Client~ コンソール・アプリケーションで実装。 -Client Credentials Grant Client~ コンソール・アプリケーションで実装。 ***関連する情報 [#tc543bde] -The ASP.NET Forums --OWIN and Authorization Code Grant Flow - Always Bad Request (Invalid Grant)~ https://forums.asp.net/t/1975505.aspx?OWIN+and+Authorization+Code+Grant+Flow+Always+Bad+Request+Invalid+Grant+ -Stack Overflow --MVC 5 application - implement OAuth Authorization code flow~ http://stackoverflow.com/questions/25845420/mvc-5-application-implement-oauth-authorization-code-flow --asp.net - Authorization_code grant flow on Owin.Security.OAuth: returns invalid_grant~ http://stackoverflow.com/questions/24515211/authorization-code-grant-flow-on-owin-security-oauth-returns-invalid-grant -その他 --AuthServerTests.cs | Source Browser~ http://sourcebrowser.io/Browse/jchannon/katanaproject/tests/FunctionalTests/Facts/Security/AuthServer/AuthServerTests.cs#207 **その他 [#ad1e79f3] 実装方法について参照したページ。 ***[[Implicitグラント種別>#kb8fee48]] [#j1c1a778] -ASP.NET WebAPI2でAjaxでOAuth認証するよ(ついでにTypeScriptとReact) - かずきのBlog@hatena~ http://blog.okazuki.jp/entry/2016/01/15/215901 -asp.net - How do you consume extra parameters~ in OAuth2 Token request within .net WebApi2 application - Stack Overflow~ http://stackoverflow.com/questions/21243996/how-do-you-consume-extra-parameters-in-oauth2-token-request-within-net-webapi2 -c# - Can't get UserManager from OwinContext in apicontroller - Stack Overflow~ http://stackoverflow.com/questions/24001245/cant-get-usermanager-from-owincontext-in-apicontroller -Simple OAuth Server: Implementing a Simple OAuth Server~ with Katana OAuth Authorization Server Components (Part 1) - Tugberk Ugurlu's Blog~ http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part-1 ***Tsmatz [#i87cb2b3] -ASP.NET SPA (JavaScript) の Web API 認証 (ASP.NET Identity) – Tsmatz~ https://blogs.msdn.microsoft.com/tsmatsuz/2014/05/20/asp-net-spa-javascript-web-api-asp-net-identity-html5biz/ **[[OAuth2.0のセキュリティについて。>OAuth#v33a7e19]] [#c75e8910] ---- Tags: [[:ASP.NET]], [[:ASP.NET MVC]], [[:ASP.NET SPA]], [[[[ASP.NET Web API]]]], [[:ASP.NET Identity]] Special thanks go to mg-san for his support.