[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]

-[[戻る>OAuth]]

* 目次 [#ba45eec0]
#contents

*概要 [#nf08aeca]
(前提知識に、[[OAuth]] 2.0 の知識を要する)

外部ログインすると、通常、

[[OAuth]] 2.0 の Authorization Server で認証されたユーザのクレームが~
Redirectエンドポイントに返るが、これは、[[OAuth]] 2.0 自体の仕様ではない。

*外部ログイン(認証)の拡張仕様 [#m5ae941c]
これは、[[OAuth]] 2.0「Authorization Codeグラント種別」の拡張仕様になる。

-通常、[[OAuth]] 2.0では、Redirectエンドポイントには、仲介コードが返り、~
仲介コードをサーバ側でAccess Tokenに変換した後、Resources Serverへアクセスし、~
必要なResources(ここでは認証されたユーザのクレーム)を取り出して返すと言う流れになる。~

-しかし、外部ログインでは、Redirectエンドポイントに直接、このクレームが返る~
(外部ログイン・ライブラリ上で、仲介コード → Access Token → クレームへの変換処理をしている)。

**ASP.NET Identity用のMicrosoftアカウントの外部ログイン・ライブラリの場合 [#jf7626f6]
動作を分析した所、

-実際のRedirectエンドポイントは、~
http://localhost:nnnnn/signin-microsoft

-アプリケーションのCallbackのエンドポイントが、~
/Account/ExternalLoginCallback

となっている。

HTTPSのため、仲介コード → Access Tokenの、Responseを確認できず、~
[[OpenID Connect]]で実装されてる可能性もあると考えたが、~
scopeパラメタに「openid」の値を確認できなかったので、[[OAuth]] 2.0拡張と思われる。

***Redirectエンドポイント [#yd211b3f]
仲介コード → Access Token → クレームへの変換処理を行っている模様。

-GET http://localhost:nnnnn/signin-microsoft?code=AAAAA&state=BBBBB HTTP/1.1

-Cookie:
--ASP.NET_SessionId=XXXXX
--__RequestVerificationToken=YYYYY
--.AspNet.Correlation.Microsoft=ZZZZZ1

***Callbackのエンドポイント [#mc069e8d]
この時点で情報は全て、.AspNet.ExternalCookieに同梱されるもよう。~
(恐らく、クレームなどの情報の露見を防ぐためと思われる)

-GET http://localhost:nnnnn/Account/ExternalLoginCallback HTTP/1.1

-Cookie:
--ASP.NET_SessionId=XXXXX
--__RequestVerificationToken=YYYYY
--.AspNet.ExternalCookie=ZZZZZ2

***遷移元への遷移 [#z6e7095a]
認証後、遷移元へ遷移した後には、外部ログインの形跡は綺麗に消えている。

-GET http://localhost:nnnnn/ HTTP/1.1

-Cookie:
--ASP.NET_SessionId=XXXXX
--__RequestVerificationToken=YYYYY
--.AspNet.TwoFactorRememberBrowser=ZZZZZ3
--.AspNet.ApplicationCookie=ZZZZZ4

***セキュリティに関する考慮点 [#j218c1c3]
以下をライブラリ内で処理することで、セキュリティを高くしている。

-外部ログインを、ライブラリ内部で処理して、
--ユーザの実装ミスによる仲介コード、Access Token等の露見を防いでいる。
--長目のRequestVerificationToken値を使用している。

-Redirectエンドポイント→Callbackのエンドポイント間で、
--仲介コード、Access Token等が露見しないよう、エンドポイントを2段構成にしている。
--エンドポイント間のインターフェイスにCookie(ExternalCookie)を使用し、遷移後、直ちに削除している。

**ASP.NET Identity用のGoogleアカウントの外部ログイン・ライブラリの場合 [#n558399c]
***Redirectエンドポイント [#t80d5fb3]
***Callbackのエンドポイント [#cdbada51]
***遷移元への遷移 [#z20030fe]
***セキュリティに関する考慮点 [#i86b0b7b]

**Bearer Tokenやクレームを[[JWT]]フォーマットに変更する [#yf9cec19]
改竄、置換、CSRF(XSRF)などを検出できる。詳しくは[[コチラ>JWT#f9d1b3ca]]を参照。
Tokenやクレームに、[[JWT]]フォーマットを使用すれば、~
改竄、置換、CSRF(XSRF)などを検出することができる。

詳しくは[[コチラ>JWT#f9d1b3ca]]を参照。

*User-Agentやスマホネイティブでの外部ログインについての考察 [#y96989f1]

**課題 [#y4777e16]
問題はサーバ間で認証する必要があること。
問題は、クライアント(User-Agentやスマホネイティブ)という仲介者が存在する中で、サーバ間認証をする必要があること。

***課題1 [#n3075467]
しかし、User-Agentやスマホネイティブで上記外部ログイン方式に習い、~
User-Agentやスマホネイティブで上記外部ログイン方式に習い、~
[[OAuth]] 2.0の「Implicitグラント種別」でClientではなく、~
"仲介者"であるUser-Agentやスマホネイティブに返したクレームを使って~
サーバ認証というのも意味不明な(認証になって無い)仕様なので、~

結局、User-Agentやスマホネイティブでも

-「Authorization Codeグラント種別」で
-サーバ(AuthorizationServerとClient)間で

外部ログインするしか無いのか?

***課題2 [#hd0bbd17]
外部ログインした場合、
外部ログインした場合、その後に、

その後に、サーバとクライアント(User-Agentやスマホネイティブ)間で~
認証するための認証チケット(的なモノ)を、サーバが、~
"仲介者"であるクライアントへ発行する必要がある。
サーバとクライアント(User-Agentやスマホネイティブ)間で認証するための認証チケット(的なモノ)を、~
サーバが、(改竄、置換などの攻撃を行う可能性のある)"仲介者"であるクライアントへ発行する必要がある。

**解決 [#z2e54cac]
[[JWT]]を使用すれば、クライアントを経由しても、~
安全にサーバ間で認証可能な、認証チケット(的なモノの)を発行できる。

***方法 [#zdd6e43b]
[[コチラ>JWT#yd304024]]を参照。

***Hybrid(Webアプリケーション)の場合 [#o65b7360]
Authorization Codeグラント種別で、~
認証チケット(的なモノの → JWTのアサーション)を取得できる。

***SPA & WebAPIの場合 [#l187d128]
Implicitグラント種別だと、アクセストークンが露見するので、~
同様に、Authorization Codeグラント種別で、~
認証チケット(的なモノの → JWTのアサーション)ダケを取得しても良い。

***スマホネイティブ & WebAPIの場合 [#oc41f23b]

*参考 [#cd0c604f]
-[[OAuth]]
-[[ASP.NET Identityの外部ログイン]]
-[[ASP.NET IdentityによるSTS実装]]
--[[ASP.NET IdentityのOAuthによるSTS実装]]

----
Tags: [[:認証基盤]], [[:ASP.NET Identity]], [[:OAuth]]


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS