SlideShare a Scribd company logo
#springday
∼ Basic認証? APIキー? OAuth 2.0? OpenID Connect? ∼
Spring Security で作る
Web API アクセス制御の
最適解
クラスメソッド株式会社
都元ダイスケ
SPRING DAY 2016
グラントウキョウサウスタワー41F
ROOM3-5
2016/11/18 (Fri)
#springday
よく訓練されたアップル信者、都元です。
Webアプリ屋・AWS屋
AWS歴 5年強(2011夏頃∼)
Java歴 約10年(2006頃∼)
Twitter @daisuke_m
その他戦場

Spring, Gradle, OAuth, OpenID Connect
自己紹介 2
#springday
【 序 章 】
概要、お詫びと訂正、
そして怒涛の結論へ
3
#springday
マイクロサービスアーキテクチャが話題を集め、

コンポーネントのWeb API化が更なる急加速を見せる昨今。
とは言え「誰でも自由に叩いて良い」Web APIなんてのは事実上無く、

ほぼ全てのケースで何かしらのアクセス制御が必要になります。
今日する話 4
Spring Security もサポートする昔ながらの「Basic認証」。

        古い、ということは、悪いソリューションなのか?
最近のAPIのアクセス制御と言えば「OAuth 2.0」がトレンディ?

        Spring Security OAuth もあるし!
一方でAWSは「APIキー方式」を採用。なぜAWSはOAuth2ではないのか?
Spring Security はまだ公式にサポートしていない「OpenID Connect」とは一体…?
Webにおけるアクセス制御の歴史を振り返りつつ、様々なAPIの立ち位
置と共に、その最適解を探っていきたいと思います。
#springday
Springの話
Webブラウザによる通信の話
ステートフルなAPIの話
HTTP(not HTTPS)通信の話
もう2016年っすよ。HTTPS使おう。
今日しない話 5
#springday
スライドを書き進めても、

Springの話やJavaのコードが

ほとんど出てきませんでした(汗
無理やりひねり出しても仕方ないので

気楽な感じで開き直って、

イベント趣旨からズレた話します!
お詫び 6
#springday
結論(!?) 7
case by case
結局APIの認証は何を使えばいいの?
#springday
認証:通信相手が誰か、確認すること。

  (= なりすましでないことの証明)
認可:リクエストが許可されるかどうかを決
めること。
認証と認可は、本来、相互に独立した概念。
しかし多くの場合、認証した上で

  「その主体が権限を持つかどうか」

という視点で認可を行う。
認証と認可 8
#springday
クライアントは全てprivate networkに居る。

つまりAPI サーバへの通信経路は全てprivate。

牧歌的な世界。敵はいない。
そもそも認証(なりすましでないことの証明)要る?
SSLも要る? パフォーマンスを犠牲にしてまで。
まずは private network の世界 9
#springday
七人の敵どころじゃない。
アクセス制御の話を聞きに来てる時点で、

SSL/TLS必須。必須。必須。
天気予報とか郵便番号検索とか、

誰が見ても害がないような情報の

read-only アクセスでない限り。
それだって最近は認証するケースが多い。

OpenWeatherMap とか。
global network に晒した途端 10
#springday
WHAT YOU ARE (inherence factor)
顔貌、声、指紋、署名など、その人自身の提示。
WHAT YOU HAVE (possession factor)
身分証、携帯電話等、その人だけが持っているものの提示。
WHAT YOU KNOW (knowledge factor)
パスワード、秘密の質問等、その人だけが知っていることの提示。
認証の方法 11
#springday
静的・無期限のクレデンシャル

  例: パスワード
静的・有期限のクレデンシャル

  例: OAuth2 アクセストークン・セッションID
動的なクレデンシャル

  例: リクエスト署名 (HMAC)
クレデンシャルの分類 12
#springday
【 第 1 章 】
Basic認証
13
(と、Digest認証)
#springday
HTTPではパスワードが平文で流れるので論外。
ログアウトできない。
「パスワードを保存する」チェックボックス。
見た目かっこ悪い。
(ブラウザのHTTP-BASIC認証) 14
#springday
散々disられているが、決定的な否定理由が見つからない。
BASIC認証 over HTTPS は、OAuth 2.0(後述)及び
その周辺プロトコルにおける、1つの技術要素。
Access Token Request, Revocation, Introspection
API における BASIC認証 over HTTPS 15
Is HTTPS and Basic Authentication secure enough for banking webservices (RESTful)?
http://security.stackexchange.com/questions/44811/
#springday
HTTPSという前提条件の下、適切に運用すれば

直ちに安全に影響を及ぼすレベルではない。
ただ、敢えて勧めはしない。なぜなら…
API における BASIC認証 over HTTPS 16
#springday
Attack windowが大きい。
リクエスト毎に静的・無期限なクレデンシャルが

毎回流れる。
SSL/TLSとて万能ではない。
Heartbleed, POODLE, FREAK, etc.
BASIC認証 over HTTPS を否定するとすれば 17
#springday
静的なクレデンシャルが毎回流れるのが問題ならば、

nonceを利用したチャレンジ&レスポンスで、

動的なクレデンシャルにしてしまえば良いのでは?
チャレンジ&レスポンスなので、

HTTPリクエストが必ず2往復する。
結論:Web APIには向かない。
Digest認証 18
#springday
【 第 2 章 】
APIキー署名
19
#springday
AWSのAPIが採用している認証方式。
HMAC(ハッシュ関数に基づくメッセージ認証符号)
hash( secret + message ) の値は

secretを知らなければ計算できないでしょ?
リクエスト署名用 API キー 20
注:上記の式は、イメージです。素人が素朴に作ったオレオレHMACには脆弱性が発見されており、

  HMACの算出は、実際はもうちょっと複雑な式を使います。
#springday
message = リクエスト内容+現在時刻 等
secret = シークレット・アクセスキー
上記でHMACを計算、これを署名とする。
リクエストと共に、ヘッダで署名を送る。
署名は動的クレデンシャル。
HMACによるリクエスト署名 21
実は、OAuth 1.0a はこんな感じの仕組みでリクエストを行う。
つまり、リクエスト毎に面倒な計算が必要。
#springday
RFC的なスタンダードは存在しない。(欲しい)
署名算出にあたって、"aws4_request" という

文字列定数を利用するオレオレ感。
V1∼4までがあるが、V1は脆弱なので利用しない。
V4の利用を推奨。
AWS Signature Version 4 22
#springday
23
幕間
#springday
最近、都元がやってるお仕事です。
要するに、ECサイト等を作るためのAPIサービス
商品やカテゴリのマスメンや検索
顧客管理
注文や決済の処理
prismatix 24
ここで一旦、CMです。 25
#springday
prismatix の開発を取り巻く環境 26
#springday
都元、前職は某スタートアップ。
現職、クラスメソッド (ブログの会社?)
スタートアップとしての prismatix 27
#springday
prismatixは、UI は提供しません。APIだけ。
ECサイトの UI を持つフロントエンドシステムは、
prismatix API を利用する「クライアント」
「顧客」「クライアント」「prismatix」
3者のアイデンティティ(ID)を連携、コントロール
するアクセス制御機構。それが OAuth 2.0 。
prismatix API 28
#springday
【 第 3 章 】
OAuth 2.0
29
#springday
認証をするための仕組みじゃねェ。
認可をするための仕組みでさえねェ。
A があらかじめもっている認可を B に対して

部分的に委譲するための仕組み。
そもそも OAuth とは 30
認証:通信相手が誰か、確認すること。
認可:リクエストが許可されるかどうかを決めること。
#springday
3者(本当は4者だけけど)間のやり取りで、

エンドユーザの権限を、クライアントに委譲する手続き。
複雑。超複雑。
クライアントは、ユーザから委譲を受けた証として、

「ユーザのIDとpass」ではなく「アクセストークン」を
入手する。
アクセストークンは、静的だが有期限のクレデンシャル。
OAuth の概要 31
#springday
一般的な

API アクセス制御
OAuthによるアクセス制御の特徴 32
OAuth による

アクセス制御
#springday
#springday
通常は、クライアントが全権を握る。
クライアントに認証を受けたユーザが、

クライアントの監督の下に、

クライアントの権限を以って、APIアクセス。
OAuthは、エンドユーザが全権掌握。
神様であるエンドユーザ様の許しを得たクライアントが、

エンドユーザ様の名の下に、

委譲を受けた権限を行使することによる、APIアクセス。
強いのは、クライアントか、エンドユーザか。 33
#springday
エンドユーザは神様である前提のプロトコル。
つまり、エンドユーザに対する認可の仕組みは

定義していない。(スコープ外)
OAuth 2.0 におけるエンドユーザの権限管理 34
#springday
認証

Authentication userAuthentication;
エンドユーザが持つ権限(認可) 

Collection<GrantedAuthority> userAuthorities

= userAuthentication.getGrantedAuthorities();
OAuth2における認証(直接的にはクライアントの認証)

OAuth2Authentication oauth2AuthN; // (has-a userAuthentication)
OAuth2においてエンドユーザから委譲を受けた権限の範囲

Set<String> scopes

= oauth2AuthN.getOAuth2Request().getScope();
Client Credentials 認証においてクライアントが持つ権限(認可)

Collection<GrantedAuthority> clientAuthorities

= oauth2AuthN.getOAuth2Request().getAuthorities();
Spring security のモデル 35
#springday
【 第 4 章 】
OpenID Connect
36
#springday
むしろ OAuth 2.0 よりもシンプル。
個人的に、とっっっっても面白い技術。
でも実は Web API の認証には

あんまり関係が深くない。
というわけで、今日の話のスコープ外。
OpenID Connect 37
#springday
あるところに、とあるアプリがあり、それを操作しているエンドユーザがいました。
アプリはエンドユーザが誰なのか知りたくなりました。(ユーザを認証したい)
が、アプリ自身ではユーザのパスワードを管理したくありません。
そこでアプリは、第三者の「既にパスワードを管理しているシステム」(OpenID Provider) に、
エンドユーザを連れて行って(リダイレクト)、代わりに認証をしてもらいました。
OpenID ProviderはID/passを確認したら、「この人は都元さんだよ」というデータに電子署
名をつけて、アプリに渡します。
アプリは、OpenID Providerの公開 を使って署名を検証します。
検証が成功するということは、この人は確かに都元さんなんだ、と確認が持てます。
もし正しいID/passを示せないのであれば、OpenID Providerはこのデータに署名するわけが
ないのだから。
(OpenID Connect がしてくれること) 38
#springday
まとめ
39
#springday
認証と認可は複雑。
本当に仕組みが必要か、考える。
BASIC認証 over HTTPS は害悪ではない。
が、お勧めもしない。
クライアントを神に位置づけるのであれば、

APIキー署名方式は適切な選択肢。
ただし、仕様がオレオレ化するので、標準化が望まれる。
まとめ 40
#springday
OAuth は2つの主体間で認可を委譲する複雑なモデル。
オーバースペックの可能性があるので、要熟考。
OpenID Connect
Web API 認証には縁が深くない。
でも面白いヨ。
まとめ 41
#springday
42
絶賛エンジニア募集中

More Related Content

Spring Day 2016 - Web API アクセス制御の最適解

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy