Authentication Strategies
frontendのロードマップにチートシート的なものが書いてあるので読んでいく
Basic Authentication
HTTPでリソースへのアクセスを認証するメカニズム
認証情報はリクエストヘッダーに送信される
Authorization: Basic [Base64エンコードされたユーザー名とパスワード]
Step 1
クライアントはprotected URLにアクセスしようとする
Step 2
リクエストのAuthorizationヘッダーが有効なユーザー名とパスワードか、サーバーでチェックする
invalid: 401
valid: 200
realm or protection space
同じ認証情報を使用するページのグループのことらしい。
401で返ってきた時にユーザーにどのrealmか通知する。
Step 3
ブラウザはwww-authenticate
ヘッダーを検出して、認証情報入力のアラートを表示する
Step 4
ユーザーが認証情報を送信すると、ブラウザがbase64でエンコードして次のリクエストで送信する。認証情報はリクエストのAuhtoriazationヘッダーに含まれる
Step 5
Step 2へ...
Basic認証はAPIでも使用できますが、その場合は通常のトークンベースの認証と同様の扱いになります。
Basic認証はTLS/HTTPSじゃないとセキュアではない。デコードできてしまうから。
BearerはOAuth2.0用?
Session Based Authentication
ユーザーには一意の識別子が割り当てられ、この識別子はサーバーのメモリに保存されます。クライアントはすべてのリクエストにこのセッションIDを送信し、サーバーはそれを使用してユーザーを識別します。
ステートフルな認証方法(認証セッションは取り消すことができない)
Step 1
クライアントがログインリクエストを送る
Step 2
サーバーは認証情報を検証し、セッションを作成してメモリに保存、生成されたセッションIDを返す
セッションIDはランダムで一意な識別子
セッションIDはredis、メモリ、DB、ファイルシステムなど格納してもいい
Step 3
クライアントはセッションIDを受け取り、クッキーが有効な場合はクッキー、それ以外ではローカルストレージ、セッションストレージに保存する
Step 4
クライアントは次のリクエストでセッションIDを一緒に送る
サーバーはそのセッションIDがストレージに存在するか確認する
Step 5
ユーザーがログアウトすると、セッションは破棄(クッキーが削除され、サーバーからセッションが削除される)され、同じセッションIDは使用できなくなる
Token Based Authentication
Basic認証では毎回ユーザーとパスワードが送られるが、トークンベース認証は、毎回クラインとからサーバーにトークンが送られる
トークンはサーバーで生成した文字列
Step 1
クライアントがサーバーに認証情報を送る
トークンを生成するため
Step 2
サーバーが認証情報が正しいかチェックしてレスポンスを返す
- invalid: 422
- Error response
- valid: 200
- token in body or header
Step 3
クライアントはこのトークンをローカルストレージまたはクッキーに保存して、その後のリクエストで送信する
サーバーはトークンを検証して、401か200を返す
トークンの特性
- ランダムな文字列
- 有効期限があり、その期限を過ぎると使えなくなる
- 通常、Authorizationヘッダーに含まれる
- サーバーはトークンを保存しない(ステートレス)
- 通常、トークンは秘密鍵で署名されており、改ざんを検出できる
- トークンは不透明(Opaque)または自己完結型(Self-Contained)
ステートレスってどういうことかと思ってたけど、トークンは下記のどちらかであるらしい
- Opaque
- ランダムな文字列であり、認証サーバーによって検証可能。セッションIDのようなもの
- たぶん秘密鍵の話だと思う
- ランダムな文字列であり、認証サーバーによって検証可能。セッションIDのようなもの
- Self-Contained
- JWTのようにトークンにデータが含まれている
- クライアントで確認できる
トークンベースの認証戦略の種類
- SWT(Simple Web Tokens)
- JWT(JSON Web Tokens)
- OAuth(Open Authorization)
- SAML(Security Assertions Markup Language)
- OpenID
セッションと同じやんけ、と思ってたけどサーバーでの値の持ち方が、ステートフルかステートレスかで違うっぽい
JWT Authentication
トークンベースの認証方式。RFC7519に基づく。
認証および安全な情報交換にしようできる。
安全な情報交換とは?
他のトークン認証戦略と同様だけど、トークンの生成方法が異なる。
トークンの特徴
トークンは通常URLセーフな文字列で、サーバーにヘッダー、ボディ、またはURLで渡すことができる。トークンは自己完結型で、データを保持している。誰でもその内容を見ることができる。
詳細は元資料にあるので割愛するが、ドット区切りで3つのパートに分割される
- header
- payload
- signature
また、JWTの仕様として省略名が予約されている
今までJSONのデータ項目といっていたJSONのキーと値のペアはJWTでは「クレーム(Claim)」と呼び、キー名は「クレーム名」、値は「クレーム値」と呼ばれます。
Step 1
トークン生成のためにユーザーとパスワードをリクエストする
Step 2
認証情報を検証する
Step 3
シークレットキーを使ってトークンを生成
Step 4
JWTを返す
Step 5
JWTをヘッダーにもった状態で、あるセキュアなエンドポイントにリクエストを送る
Step 6
JWTをシークレットキーを使って検証する
(つまり、payloadが改ざんされてないかsignatureをチェックするってことかな)
Step 7
レスポンスを返す
OAuth — Open Authorization
SSO — Single Sign On
関連しているが独立している複数のサービスに対して、単一のユーザーパスワードでログインできる認証戦略
Googleがいろんなサービス使えるみたいなやつらしい
SAML - Security Assertion Markup Language
当事者間で認証および認可データを交換するための仕様。SSOまたはSAML実装には、3つの当事者が関与している
- User
- Identity Provider(IDP)
- Userの認証・認可の情報をもってる
- Service Provider(SP)
- 特定のサービスやリソースを提供する組織や個人のこと
- ユーザーの認証をIDPに委託する
SAMLアサーションは認証情報を含むXML文書。信頼性を検証するために署名されている。
IDPはSPに対して、SAMLアサーションを送る
SPはそれによって許可する
IDP XML
- Configurations
- SAML assertionにemailが必要だよ、などの情報
- Certificantes
- 証明書はアサーションの署名を検証するために使用され、データが信頼できることを確認する
たしかになんとなくOAuthっぽい仕組みにも感じる
OAuthは認可だし暗号化も行われないけど柔軟、SSOに使えない
SAMLは認証認可につかえるし大規模で暗号化されたデータ、SSOに使える
ちょっと用途が違うものらしい
OpenID Connect
Keycloak