spring day 2016 - web api アクセス制御の最適解

42
#springday ~ Basic認証? APIキー? OAuth 2.0? OpenID Connect? ~ Spring Security で作る Web API アクセス制御の 最適解 クラスメソッド株式会社 都元ダイスケ SPRING DAY 2016 グラントウキョウサウスタワー41F ROOM3-5 2016/11/18 (Fri)

Upload: -

Post on 06-Jan-2017

6.190 views

Category:

Technology


2 download

TRANSCRIPT

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

#springday

~ Basic認証? APIキー? OAuth 2.0? OpenID Connect? ~

Spring Security で作る Web API アクセス制御の

最適解

クラスメソッド株式会社 都元ダイスケ

SPRING DAY 2016 グラントウキョウサウスタワー41F

ROOM3-5 2016/11/18 (Fri)

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

#springday

よく訓練されたアップル信者、都元です。

Webアプリ屋・AWS屋 AWS歴 5年強(2011夏頃~) Java歴 約10年(2006頃~)

Twitter @daisuke_m

その他戦場Spring, Gradle, OAuth, OpenID Connect

自己紹介 2

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

#springday

【 序 章 】 概要、お詫びと訂正、 そして怒涛の結論へ

3

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

#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の立ち位置と共に、その最適解を探っていきたいと思います。

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

#springday

Springの話

Webブラウザによる通信の話

ステートフルなAPIの話

HTTP(not HTTPS)通信の話

もう2016年っすよ。HTTPS使おう。

今日しない話 5

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

#springday

スライドを書き進めても、Springの話やJavaのコードがほとんど出てきませんでした(汗

無理やりひねり出しても仕方ないので気楽な感じで開き直って、イベント趣旨からズレた話します!

お詫び 6

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

#springday

結論(!?) 7

case by case結局APIの認証は何を使えばいいの?

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

#springday

認証:通信相手が誰か、確認すること。   (= なりすましでないことの証明)

認可:リクエストが許可されるかどうかを決めること。

認証と認可は、本来、相互に独立した概念。

しかし多くの場合、認証した上で  「その主体が権限を持つかどうか」 という視点で認可を行う。

認証と認可 8

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

#springday

クライアントは全てprivate networkに居る。つまりAPI サーバへの通信経路は全てprivate。牧歌的な世界。敵はいない。

そもそも認証(なりすましでないことの証明)要る?

SSLも要る? パフォーマンスを犠牲にしてまで。

まずは private network の世界 9

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

#springday

七人の敵どころじゃない。

アクセス制御の話を聞きに来てる時点で、SSL/TLS必須。必須。必須。

天気予報とか郵便番号検索とか、誰が見ても害がないような情報のread-only アクセスでない限り。

それだって最近は認証するケースが多い。OpenWeatherMap とか。

global network に晒した途端 10

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

#springday

WHAT YOU ARE (inherence factor)

顔貌、声、指紋、署名など、その人自身の提示。

WHAT YOU HAVE (possession factor)

身分証、携帯電話等、その人だけが持っているものの提示。

WHAT YOU KNOW (knowledge factor)

パスワード、秘密の質問等、その人だけが知っていることの提示。

認証の方法 11

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

#springday

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

静的・有期限のクレデンシャル  例: OAuth2 アクセストークン・セッションID

動的なクレデンシャル  例: リクエスト署名 (HMAC)

クレデンシャルの分類 12

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

#springday

【 第 1 章 】 Basic認証

13

(と、Digest認証)

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

#springday

HTTPではパスワードが平文で流れるので論外。

ログアウトできない。

「パスワードを保存する」チェックボックス。

見た目かっこ悪い。

(ブラウザのHTTP-BASIC認証) 14

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

#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/

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

#springday

HTTPSという前提条件の下、適切に運用すれば直ちに安全に影響を及ぼすレベルではない。

ただ、敢えて勧めはしない。なぜなら…

API における BASIC認証 over HTTPS 16

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

#springday

Attack windowが大きい。

リクエスト毎に静的・無期限なクレデンシャルが毎回流れる。

SSL/TLSとて万能ではない。

Heartbleed, POODLE, FREAK, etc.

BASIC認証 over HTTPS を否定するとすれば 17

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

#springday

静的なクレデンシャルが毎回流れるのが問題ならば、nonceを利用したチャレンジ&レスポンスで、動的なクレデンシャルにしてしまえば良いのでは?

チャレンジ&レスポンスなので、HTTPリクエストが必ず2往復する。

結論:Web APIには向かない。

Digest認証 18

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

#springday

【 第 2 章 】 APIキー署名

19

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

#springday

AWSのAPIが採用している認証方式。

HMAC(ハッシュ関数に基づくメッセージ認証符号)

hash( secret + message ) の値はsecretを知らなければ計算できないでしょ?

リクエスト署名用 API キー 20

注:上記の式は、イメージです。素人が素朴に作ったオレオレHMACには脆弱性が発見されており、   HMACの算出は、実際はもうちょっと複雑な式を使います。

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

#springday

message = リクエスト内容+現在時刻 等

secret = シークレット・アクセスキー

上記でHMACを計算、これを署名とする。

リクエストと共に、ヘッダで署名を送る。

署名は動的クレデンシャル。

HMACによるリクエスト署名 21

実は、OAuth 1.0a はこんな感じの仕組みでリクエストを行う。 つまり、リクエスト毎に面倒な計算が必要。

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

#springday

RFC的なスタンダードは存在しない。(欲しい)

署名算出にあたって、"aws4_request" という文字列定数を利用するオレオレ感。

V1~4までがあるが、V1は脆弱なので利用しない。

V4の利用を推奨。

AWS Signature Version 4 22

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

#springday

23

幕間

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

#springday

最近、都元がやってるお仕事です。

要するに、ECサイト等を作るためのAPIサービス

商品やカテゴリのマスメンや検索

顧客管理

注文や決済の処理

prismatix 24

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

ここで一旦、CMです。 25

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

#springday

prismatix の開発を取り巻く環境 26

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

#springday

都元、前職は某スタートアップ。

現職、クラスメソッド (ブログの会社?)

スタートアップとしての prismatix 27

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

#springday

prismatixは、UI は提供しません。APIだけ。

ECサイトの UI を持つフロントエンドシステムは、prismatix API を利用する「クライアント」

「顧客」「クライアント」「prismatix」

3者のアイデンティティ(ID)を連携、コントロールするアクセス制御機構。それが OAuth 2.0 。

prismatix API 28

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

#springday

【 第 3 章 】 OAuth 2.0

29

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

#springday

認証をするための仕組みじゃねェ。

認可をするための仕組みでさえねェ。

A があらかじめもっている認可を B に対して 部分的に委譲するための仕組み。

そもそも OAuth とは 30

認証:通信相手が誰か、確認すること。 認可:リクエストが許可されるかどうかを決めること。

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

#springday

3者(本当は4者だけけど)間のやり取りで、 エンドユーザの権限を、クライアントに委譲する手続き。複雑。超複雑。

クライアントは、ユーザから委譲を受けた証として、 「ユーザのIDとpass」ではなく「アクセストークン」を入手する。

アクセストークンは、静的だが有期限のクレデンシャル。

OAuth の概要 31

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

#springday

一般的なAPI アクセス制御

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

OAuth によるアクセス制御

#springday

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

#springday

通常は、クライアントが全権を握る。

クライアントに認証を受けたユーザが、クライアントの監督の下に、クライアントの権限を以って、APIアクセス。

OAuthは、エンドユーザが全権掌握。

神様であるエンドユーザ様の許しを得たクライアントが、エンドユーザ様の名の下に、委譲を受けた権限を行使することによる、APIアクセス。

強いのは、クライアントか、エンドユーザか。 33

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

#springday

エンドユーザは神様である前提のプロトコル。

つまり、エンドユーザに対する認可の仕組みは定義していない。(スコープ外)

OAuth 2.0 におけるエンドユーザの権限管理 34

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

#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

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

#springday

【 第 4 章 】 OpenID Connect

36

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

#springday

むしろ OAuth 2.0 よりもシンプル。

個人的に、とっっっっても面白い技術。

でも実は Web API の認証にはあんまり関係が深くない。

というわけで、今日の話のスコープ外。

OpenID Connect 37

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

#springday

あるところに、とあるアプリがあり、それを操作しているエンドユーザがいました。

アプリはエンドユーザが誰なのか知りたくなりました。(ユーザを認証したい)

が、アプリ自身ではユーザのパスワードを管理したくありません。

そこでアプリは、第三者の「既にパスワードを管理しているシステム」(OpenID Provider) に、エンドユーザを連れて行って(リダイレクト)、代わりに認証をしてもらいました。

OpenID ProviderはID/passを確認したら、「この人は都元さんだよ」というデータに電子署名をつけて、アプリに渡します。

アプリは、OpenID Providerの公開鍵を使って署名を検証します。

検証が成功するということは、この人は確かに都元さんなんだ、と確認が持てます。

もし正しいID/passを示せないのであれば、OpenID Providerはこのデータに署名するわけがないのだから。

(OpenID Connect がしてくれること) 38

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

#springday

まとめ

39

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

#springday

認証と認可は複雑。 本当に仕組みが必要か、考える。

BASIC認証 over HTTPS は害悪ではない。 が、お勧めもしない。

クライアントを神に位置づけるのであれば、 APIキー署名方式は適切な選択肢。 ただし、仕様がオレオレ化するので、標準化が望まれる。

まとめ 40

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

#springday

OAuth は2つの主体間で認可を委譲する複雑なモデル。 オーバースペックの可能性があるので、要熟考。

OpenID Connect Web API 認証には縁が深くない。 でも面白いヨ。

まとめ 41

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

#springday

42

絶賛エンジニア募集中