SlideShare a Scribd company logo
1 of 22
Download to read offline
1
今こそ知りたいSpring Security
2020/12/17
日本Springユーザ会
土岐 孝平
自己紹介
• 土岐 孝平
• 合同会社 現場指向
• Webアプリ「メモラキー」の運営
• システム開発の支援
• 研修の講師
• 書籍の執筆
2
[改訂新版]Spring入門https://www.memorarchy.com
想定する聴講者
• なんとなく使ってはいるが、裏で何が起こってるのか
わからず、もやもやしている
• 少し触ったけど、難しそうなので自前にしようか悩ん
でいる
3
Spring Securityに触ったことがある方が前提です
本セッションの目的
• Spring Securityが裏で何をやっているかを知って、
問題が起きたときのデバッグや、カスタマイズ方法
の調査を円滑にする
• キーとなる以下の2つを抑える
– Security Filter Chain
– Security Context
4
網羅的な機能の説明や、設定ノウハウの説明は行いません
Security Filter Chainとは?
• Spring Securityが提供するFilter※の繋がり
• Servlet Filterの仕組みを使って処理を挟み込む
• 各Filterは、認証、URLパスの認可、CSRF防止などの役割
を持つ
5
※ 個々のFilterは
ServletのFilterイン
タフェースを実装し
ているが、Servletコ
ンテナに登録されて
いる訳ではない
Filter1
FilterX
DispatcherServlet
Delegating
FilterProxy
ブラウザ
・・
・
・・・
Controller
・・
・
ServletのFilter Chain
★Security Filter
Chain
Filter2
Spring MVCのサーブ
レット
主なFilter
6
クラス名 役割
CsrfFilter CSRFトークンの発行やチェックを行う
HeaderWriterFilter セキュリティ関連のレスポンスヘッダを
設定する
BasicAuthenticationFilter Basic認証を行う
UsernamePasswordAuthenticationFilter フォーム認証を行う
ExceptionTranslationFilter 後続の処理で発生した認証・認可の例
外をキャッチしてハンドリング(エラー画
面に遷移など)する
FilterSecurityInterceptor URLのパスの認可を行う
SecurityContextPersistenceFilter 「Security Context」を用意して、HTTP
セッションやThreadLocalに格納する
次ページで説明
Security Context
• 認証したユーザ情報(IDや権限など)を格納するオブジェクト
• HTTPセッションに保持されるため、リクエストを跨ってユー
ザ情報を参照できる
• ThreadLocal(スレッド毎にデータを管理してくれる)にも保持
されるため、リクエスト(スレッド)の処理内の任意のタイミング
でユーザ情報を参照可能
– Controllerの引数で受けとる
– 画面にユーザ情報を表示するときに参照
– staticメソッドでプログラムの任意の箇所で参照
• SecurityContextHolder.getContext()
– 認可時(URLのパス、メソッド、画面内の表示非表示)に参照
7
ThreadLocal
ThreadLocalとSecurity Contextのイメージ
8
Aさん
Bさん
Bさんの
スレッド
Bさんの
Security Context
Aさんのリクエスト(スレッド)の処理
Bさんのリクエスト(スレッド)の処理
Aさんの
スレッド
Aさんの
Security Context
Security Filter Chainの作成
• WebSecurityConfigurerAdapter を継承して
@EnableWebSecurityを付けたJavaConfigのクラス
(@Configurationを付けたクラス)を作成する
• @EnableWebSecurityがインポートしている
WebSecurityConfigurationクラスの中で、Security Filter
Chainのオブジェクトが作成される
• 標準的なFilterが自動で登録されるので、メソッドをオーバー
ライドして個別の設定を行う 9
@Configuration@Configuration
@EnableWebSecurity
public class SampleSecurityConfig extends WebSecurityConfigurerAdapter {
}
個別の設定のサンプル
10
@Configuration
@EnableWebSecurity
public class SampleSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated().and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder
= PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth
.inMemoryAuthentication()
.withUser("foo").password(encoder.encode("passfoo")).authorities("ADMIN").and()
.withUser("bar").password(encoder.encode("passbar")).authorities("USER");
}
}
「/admin」 で始まるパスは「ADMIN」権限が
必要、それ以外は認証されてればOK
Basic認証を有効にする
「foo」ユーザは「ADMIN」権限、「bar」ユーザは
「USER」権限という認証情報をメモリ上に保管
出来上がった主なオブジェクト
11
Authentication
Manager
UserDetailsService
AccessDecision
Manager
Dispatcher
Servlet
Delegating
FilterProxy
ブラウザ
・・
・
・・
・
Controller
ServletのFilter Chain
★Security Filter Chain
ID・パスワードのチェックを
行う。認証情報は
UserDetailsServieから取得
権限のチェックを行う
認証情報を取得。今回はメ
モリ上から取得
URLのパスの認可を行う
BasicAuthenticationFilter
ExceptionTranslationFilter
SecurityContextPersistenceFilter
FilterSecurityInterceptor
Basic認証を行う
Security Filter Chainの動作イメージ
• 認可が必要なURLに初回アクセスしたとき
– ※主なFilterに絞っています
12
BasicAuthenticationFilter
ExceptionTranslationFilter
SecurityContextPersistenceFilter
FilterSecurityInterceptor
DispatcherServlet
リクエスト(/admin/foo) レスポンス
HTTPセッションにSecurity Context
がないため、新しく用意する。
用意したSecurity Contextを、
ThreadLocalに入れる
Authorization ID
Context
AuthorizationヘッダからユーザID・
パスワードを取得して認証する。
OKならユーザ情報をSecurity
Contextに入れる
スルー
URLパスに設定された権限と、
Security Contextのユーザ情報の権
限を比較する。OKなら後続の処理
を呼び出す
スルー
例外が投げられた訳
ではないのでスルー
スルー
ユーザ情報入りの
Security ContextをHTTP
セッションに入れる
フォーム認証のサンプル
13
@Configuration
@EnableWebSecurity
public class SampleSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/login")
.usernameParameter("username").passwordParameter("password")
.failureUrl("/login?error");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
・・・ 省略
}
}
フォーム認証を有効にする
ログイン画面のパス。未認証のユーザ
を自動的に遷移させる
認証リクエストのパス。POST前提
認証リクエストに乗せるユーザIDとパス
ワードのパラメータ名ログイン失敗時に遷移
するパス
ログイン画面のサンプル
14
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<form th:action="@{/login}" method="post">
<input type="text" name="username" />
<input type="text" name="password" />
<input type="submit" value="送信" />
</form>
</body>
</html>
POSTメソッドを指定
※テンプレートエンジンのThymeleafを使用
Security Filter Chainの動作イメージ1/3
• 未認証のユーザが、認可が必要なURLにアクセス
15
UsernamePasswordAuthenticationFilter
ExceptionTranslationFilter
SecurityContextPersistenceFilter
FilterSecurityInterceptor
DispatcherServlet
ログイン画面にリダイレクトHTTPセッションにSecurity Context
がないため、新しく用意する。
用意したSecurity Contextを、
ThreadLocalに入れる
認証のリクエストでは無いので
スルー
リクエスト(/admin/foo)
スルー
未認証なので、
AccessDeniedExceptionをスロー
AccessDeniedExceptionをキャッチ
して、ログイン画面にリダイレクト
するレスポンスを設定。その際、
リクエストの内容をHTTPセッショ
ンに格納する(ログイン後に自動
で遷移するため)
スルー
空のSecurity Contextを
HTTPセッションに入れる。
Security Filter Chainの動作イメージ2/3
• 認証リクエストを送信
16
UsernamePasswordAuthenticationFilter
ExceptionTranslationFilter
SecurityContextPersistenceFilter
FilterSecurityInterceptor
/admin/fooにリダイレクトリクエスト(POSTの/login)
HTTPセッションから空のSecurity
Contextを取得して、ThreadLocal
に入れる。
認証リクエストだと判断して、リク
エストパラメータのID・パスワード
で認証する。認証したユーザ情
報をSecurity Contextに入れる。
HTTPセッションに格納しておいた
リクエストにリダイレクトするレス
ポンスを設定。
DispatcherServlet
ユーザ情報が入った
Security ContextをHTTP
セッションに入れる。
Security Filter Chainの動作イメージ3/3
• /admin/fooにアクセス
17
SecurityContextPersistenceFilter
FilterSecurityInterceptor
レスポンスリクエスト(/admin/foo)
HTTPセッションからSecurity
Context(ユーザ情報入り)を取得
して、ThreadLocalに入れる。
DispatcherServlet
ユーザ情報が入った
Security ContextをHTTP
セッションに入れる。
UsernamePasswordAuthenticationFilter
ExceptionTranslationFilter
認証のリクエストでは無いので
スルー
スルー
URLパスに設定された権限と、
Security Contextのユーザ情報の
権限を比較する。OKなら後続の処
理を呼び出す
スルー
例外が投げられた訳
ではないのでスルー
スルー
Security Filter Chainのログ 1/2
• どのFilterが、どの順番で動いたかをログに出力す
ることが可能
– デバッグに便利
• 設定方法
– ロガーの「org.springframework.security」をDEBUGレベルに
する
– application.propertiesでの設定例
18
logging.level.org.springframework.security=DEBUG
Security Filter Chainのログ 2/2
• 出力例
– 未認証のユーザが、認可が必要なURLにアクセスしたと
きのログ(抜粋)
19
/admin/foo at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
/admin/foo at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
No HttpSession currently exists
No SecurityContext was available from the HttpSession: null. A new one will be created.
/admin/foo at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
/admin/foo at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
/admin/foo at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
Request 'GET /admin/foo' doesn't match 'POST /logout'
/admin/foo at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
Request 'GET /admin/foo' doesn't match 'POST /login'
/admin/foo at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
saved request doesn't match
/admin/foo at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
/admin/foo at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
/admin/foo at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
/admin/foo at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
/admin/foo at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
Secure object: FilterInvocation: URL: /admin/foo; Attributes: [hasAuthority('ADMIN')]
Voter: org.springframework.security.web.access.expression.WebExpressionVoter@7d30e6, returned: -1
o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
Filterの数と処理
準が表示われる
特別な処理が行われた
らログにでる
さいごに
• Spring Securityの裏の動きのイメージが沸いて、デ
バッグやカスタマイズの作業がし易くなれば幸いで
す。
• おすすめのサイト
– Spring Securityのマニュアルの「The Big Picture」の章
• https://docs.spring.io/spring-
security/site/docs/current/reference/html5/#servlet-
architecture
20
21
ご清聴ありがとうございました
22
ライセンスについて
• JSUGマスコットアイコン(本スライド左下)が残されている場合に限り、本作品(またそれを元にした派生
作品)の複製・頒布・表示・上演を認めます。
• 非商用目的に限り、本作品(またそれを元にした派生作品)の複製・頒布・表示・上演を認めます。
• 本作品のライセンスを遵守する限り、派生作品を頒布することを許可します。

More Related Content

What's hot

LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) Hironobu Isoda
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンKentaro Yoshida
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニングyoku0825
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーションssuser070fa9
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)Takuto Wada
 
Springを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイントSpringを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイント土岐 孝平
 
Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版Yuichi Hasegawa
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みTakeshi Ogawa
 
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜Takahiko Ito
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Ryosuke Uchitate
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線MeetupMasatoshi Tada
 
Fluentdで本番環境を再現
Fluentdで本番環境を再現Fluentdで本番環境を再現
Fluentdで本番環境を再現Hiroshi Toyama
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来についてshinjiigarashi
 
Spring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のことSpring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のこと心 谷本
 

What's hot (20)

LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall ) LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
LogbackからLog4j 2への移行によるアプリケーションのスループット改善 ( JJUG CCC 2021 Fall )
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターン
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
Springを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイントSpringを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイント
 
Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組み
 
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
Elasticsearch の検索精度のチューニング 〜テストを作って高速かつ安全に〜
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
 
Fluentdで本番環境を再現
Fluentdで本番環境を再現Fluentdで本番環境を再現
Fluentdで本番環境を再現
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
SpringBootTest入門
SpringBootTest入門SpringBootTest入門
SpringBootTest入門
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
 
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
 
Spring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のことSpring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のこと
 

Similar to Spring fest2020 spring-security

Spring Framework ふりかえりと4.3新機能
Spring Framework ふりかえりと4.3新機能Spring Framework ふりかえりと4.3新機能
Spring Framework ふりかえりと4.3新機能kimulla
 
Scala 初心者向けlt
Scala 初心者向けltScala 初心者向けlt
Scala 初心者向けltKeigo Magami
 
ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜
ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜
ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜Ryo Sasaki
 
WordPressとリスク管理 at 第42回 WordBench大阪
WordPressとリスク管理 at 第42回 WordBench大阪WordPressとリスク管理 at 第42回 WordBench大阪
WordPressとリスク管理 at 第42回 WordBench大阪Kitani Kimiya
 
FuelPHP Osu Nagoya vol.1
FuelPHP Osu Nagoya vol.1FuelPHP Osu Nagoya vol.1
FuelPHP Osu Nagoya vol.1Fumito Mizuno
 
Cloud Foundry にアプリケーションを push する際の典型的な10のエラー
Cloud Foundry にアプリケーションを push する際の典型的な10のエラーCloud Foundry にアプリケーションを push する際の典型的な10のエラー
Cloud Foundry にアプリケーションを push する際の典型的な10のエラーnota-ja
 

Similar to Spring fest2020 spring-security (7)

Spring Framework ふりかえりと4.3新機能
Spring Framework ふりかえりと4.3新機能Spring Framework ふりかえりと4.3新機能
Spring Framework ふりかえりと4.3新機能
 
Rails4 security
Rails4 securityRails4 security
Rails4 security
 
Scala 初心者向けlt
Scala 初心者向けltScala 初心者向けlt
Scala 初心者向けlt
 
ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜
ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜
ゼロトラスト三銃士〜Okta x Jamf x Netskopeネタ10連発〜
 
WordPressとリスク管理 at 第42回 WordBench大阪
WordPressとリスク管理 at 第42回 WordBench大阪WordPressとリスク管理 at 第42回 WordBench大阪
WordPressとリスク管理 at 第42回 WordBench大阪
 
FuelPHP Osu Nagoya vol.1
FuelPHP Osu Nagoya vol.1FuelPHP Osu Nagoya vol.1
FuelPHP Osu Nagoya vol.1
 
Cloud Foundry にアプリケーションを push する際の典型的な10のエラー
Cloud Foundry にアプリケーションを push する際の典型的な10のエラーCloud Foundry にアプリケーションを push する際の典型的な10のエラー
Cloud Foundry にアプリケーションを push する際の典型的な10のエラー
 

More from 土岐 孝平

What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?土岐 孝平
 
SpringベースのCloud Native Application
SpringベースのCloud Native ApplicationSpringベースのCloud Native Application
SpringベースのCloud Native Application土岐 孝平
 
Microserviceの今どきのインフラを探る
Microserviceの今どきのインフラを探るMicroserviceの今どきのインフラを探る
Microserviceの今どきのインフラを探る土岐 孝平
 
OpenID Connect入門
OpenID Connect入門OpenID Connect入門
OpenID Connect入門土岐 孝平
 
これから始めるSpringのwebアプリケーション
これから始めるSpringのwebアプリケーションこれから始めるSpringのwebアプリケーション
これから始めるSpringのwebアプリケーション土岐 孝平
 
今さら聞けないDiとspring
今さら聞けないDiとspring今さら聞けないDiとspring
今さら聞けないDiとspring土岐 孝平
 
Springを使ったwebアプリにリファクタリングしよう
Springを使ったwebアプリにリファクタリングしようSpringを使ったwebアプリにリファクタリングしよう
Springを使ったwebアプリにリファクタリングしよう土岐 孝平
 
業務システムとマイクロサービス
業務システムとマイクロサービス業務システムとマイクロサービス
業務システムとマイクロサービス土岐 孝平
 
エッセンシャルCore springハンズオン
エッセンシャルCore springハンズオンエッセンシャルCore springハンズオン
エッセンシャルCore springハンズオン土岐 孝平
 
試験にでるSpring
試験にでるSpring試験にでるSpring
試験にでるSpring土岐 孝平
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理土岐 孝平
 

More from 土岐 孝平 (12)

What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?What's new in Spring Boot 2.6 ?
What's new in Spring Boot 2.6 ?
 
SpringベースのCloud Native Application
SpringベースのCloud Native ApplicationSpringベースのCloud Native Application
SpringベースのCloud Native Application
 
Microserviceの今どきのインフラを探る
Microserviceの今どきのインフラを探るMicroserviceの今どきのインフラを探る
Microserviceの今どきのインフラを探る
 
OpenID Connect入門
OpenID Connect入門OpenID Connect入門
OpenID Connect入門
 
これから始めるSpringのwebアプリケーション
これから始めるSpringのwebアプリケーションこれから始めるSpringのwebアプリケーション
これから始めるSpringのwebアプリケーション
 
今さら聞けないDiとspring
今さら聞けないDiとspring今さら聞けないDiとspring
今さら聞けないDiとspring
 
Springを使ったwebアプリにリファクタリングしよう
Springを使ったwebアプリにリファクタリングしようSpringを使ったwebアプリにリファクタリングしよう
Springを使ったwebアプリにリファクタリングしよう
 
業務システムとマイクロサービス
業務システムとマイクロサービス業務システムとマイクロサービス
業務システムとマイクロサービス
 
エッセンシャルCore springハンズオン
エッセンシャルCore springハンズオンエッセンシャルCore springハンズオン
エッセンシャルCore springハンズオン
 
試験にでるSpring
試験にでるSpring試験にでるSpring
試験にでるSpring
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理
 
vFabricを触ろう
vFabricを触ろうvFabricを触ろう
vFabricを触ろう
 

Spring fest2020 spring-security

  • 2. 自己紹介 • 土岐 孝平 • 合同会社 現場指向 • Webアプリ「メモラキー」の運営 • システム開発の支援 • 研修の講師 • 書籍の執筆 2 [改訂新版]Spring入門https://www.memorarchy.com
  • 4. 本セッションの目的 • Spring Securityが裏で何をやっているかを知って、 問題が起きたときのデバッグや、カスタマイズ方法 の調査を円滑にする • キーとなる以下の2つを抑える – Security Filter Chain – Security Context 4 網羅的な機能の説明や、設定ノウハウの説明は行いません
  • 5. Security Filter Chainとは? • Spring Securityが提供するFilter※の繋がり • Servlet Filterの仕組みを使って処理を挟み込む • 各Filterは、認証、URLパスの認可、CSRF防止などの役割 を持つ 5 ※ 個々のFilterは ServletのFilterイン タフェースを実装し ているが、Servletコ ンテナに登録されて いる訳ではない Filter1 FilterX DispatcherServlet Delegating FilterProxy ブラウザ ・・ ・ ・・・ Controller ・・ ・ ServletのFilter Chain ★Security Filter Chain Filter2 Spring MVCのサーブ レット
  • 6. 主なFilter 6 クラス名 役割 CsrfFilter CSRFトークンの発行やチェックを行う HeaderWriterFilter セキュリティ関連のレスポンスヘッダを 設定する BasicAuthenticationFilter Basic認証を行う UsernamePasswordAuthenticationFilter フォーム認証を行う ExceptionTranslationFilter 後続の処理で発生した認証・認可の例 外をキャッチしてハンドリング(エラー画 面に遷移など)する FilterSecurityInterceptor URLのパスの認可を行う SecurityContextPersistenceFilter 「Security Context」を用意して、HTTP セッションやThreadLocalに格納する 次ページで説明
  • 7. Security Context • 認証したユーザ情報(IDや権限など)を格納するオブジェクト • HTTPセッションに保持されるため、リクエストを跨ってユー ザ情報を参照できる • ThreadLocal(スレッド毎にデータを管理してくれる)にも保持 されるため、リクエスト(スレッド)の処理内の任意のタイミング でユーザ情報を参照可能 – Controllerの引数で受けとる – 画面にユーザ情報を表示するときに参照 – staticメソッドでプログラムの任意の箇所で参照 • SecurityContextHolder.getContext() – 認可時(URLのパス、メソッド、画面内の表示非表示)に参照 7
  • 9. Security Filter Chainの作成 • WebSecurityConfigurerAdapter を継承して @EnableWebSecurityを付けたJavaConfigのクラス (@Configurationを付けたクラス)を作成する • @EnableWebSecurityがインポートしている WebSecurityConfigurationクラスの中で、Security Filter Chainのオブジェクトが作成される • 標準的なFilterが自動で登録されるので、メソッドをオーバー ライドして個別の設定を行う 9 @Configuration@Configuration @EnableWebSecurity public class SampleSecurityConfig extends WebSecurityConfigurerAdapter { }
  • 10. 個別の設定のサンプル 10 @Configuration @EnableWebSecurity public class SampleSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .mvcMatchers("/admin/**").hasAuthority("ADMIN") .anyRequest().authenticated().and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); auth .inMemoryAuthentication() .withUser("foo").password(encoder.encode("passfoo")).authorities("ADMIN").and() .withUser("bar").password(encoder.encode("passbar")).authorities("USER"); } } 「/admin」 で始まるパスは「ADMIN」権限が 必要、それ以外は認証されてればOK Basic認証を有効にする 「foo」ユーザは「ADMIN」権限、「bar」ユーザは 「USER」権限という認証情報をメモリ上に保管
  • 11. 出来上がった主なオブジェクト 11 Authentication Manager UserDetailsService AccessDecision Manager Dispatcher Servlet Delegating FilterProxy ブラウザ ・・ ・ ・・ ・ Controller ServletのFilter Chain ★Security Filter Chain ID・パスワードのチェックを 行う。認証情報は UserDetailsServieから取得 権限のチェックを行う 認証情報を取得。今回はメ モリ上から取得 URLのパスの認可を行う BasicAuthenticationFilter ExceptionTranslationFilter SecurityContextPersistenceFilter FilterSecurityInterceptor Basic認証を行う
  • 12. Security Filter Chainの動作イメージ • 認可が必要なURLに初回アクセスしたとき – ※主なFilterに絞っています 12 BasicAuthenticationFilter ExceptionTranslationFilter SecurityContextPersistenceFilter FilterSecurityInterceptor DispatcherServlet リクエスト(/admin/foo) レスポンス HTTPセッションにSecurity Context がないため、新しく用意する。 用意したSecurity Contextを、 ThreadLocalに入れる Authorization ID Context AuthorizationヘッダからユーザID・ パスワードを取得して認証する。 OKならユーザ情報をSecurity Contextに入れる スルー URLパスに設定された権限と、 Security Contextのユーザ情報の権 限を比較する。OKなら後続の処理 を呼び出す スルー 例外が投げられた訳 ではないのでスルー スルー ユーザ情報入りの Security ContextをHTTP セッションに入れる
  • 13. フォーム認証のサンプル 13 @Configuration @EnableWebSecurity public class SampleSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .mvcMatchers("/admin/**").hasAuthority("ADMIN") .anyRequest().authenticated().and() .formLogin() .loginPage("/login").permitAll() .loginProcessingUrl("/login") .usernameParameter("username").passwordParameter("password") .failureUrl("/login?error"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { ・・・ 省略 } } フォーム認証を有効にする ログイン画面のパス。未認証のユーザ を自動的に遷移させる 認証リクエストのパス。POST前提 認証リクエストに乗せるユーザIDとパス ワードのパラメータ名ログイン失敗時に遷移 するパス
  • 14. ログイン画面のサンプル 14 <!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <body> <form th:action="@{/login}" method="post"> <input type="text" name="username" /> <input type="text" name="password" /> <input type="submit" value="送信" /> </form> </body> </html> POSTメソッドを指定 ※テンプレートエンジンのThymeleafを使用
  • 15. Security Filter Chainの動作イメージ1/3 • 未認証のユーザが、認可が必要なURLにアクセス 15 UsernamePasswordAuthenticationFilter ExceptionTranslationFilter SecurityContextPersistenceFilter FilterSecurityInterceptor DispatcherServlet ログイン画面にリダイレクトHTTPセッションにSecurity Context がないため、新しく用意する。 用意したSecurity Contextを、 ThreadLocalに入れる 認証のリクエストでは無いので スルー リクエスト(/admin/foo) スルー 未認証なので、 AccessDeniedExceptionをスロー AccessDeniedExceptionをキャッチ して、ログイン画面にリダイレクト するレスポンスを設定。その際、 リクエストの内容をHTTPセッショ ンに格納する(ログイン後に自動 で遷移するため) スルー 空のSecurity Contextを HTTPセッションに入れる。
  • 16. Security Filter Chainの動作イメージ2/3 • 認証リクエストを送信 16 UsernamePasswordAuthenticationFilter ExceptionTranslationFilter SecurityContextPersistenceFilter FilterSecurityInterceptor /admin/fooにリダイレクトリクエスト(POSTの/login) HTTPセッションから空のSecurity Contextを取得して、ThreadLocal に入れる。 認証リクエストだと判断して、リク エストパラメータのID・パスワード で認証する。認証したユーザ情 報をSecurity Contextに入れる。 HTTPセッションに格納しておいた リクエストにリダイレクトするレス ポンスを設定。 DispatcherServlet ユーザ情報が入った Security ContextをHTTP セッションに入れる。
  • 17. Security Filter Chainの動作イメージ3/3 • /admin/fooにアクセス 17 SecurityContextPersistenceFilter FilterSecurityInterceptor レスポンスリクエスト(/admin/foo) HTTPセッションからSecurity Context(ユーザ情報入り)を取得 して、ThreadLocalに入れる。 DispatcherServlet ユーザ情報が入った Security ContextをHTTP セッションに入れる。 UsernamePasswordAuthenticationFilter ExceptionTranslationFilter 認証のリクエストでは無いので スルー スルー URLパスに設定された権限と、 Security Contextのユーザ情報の 権限を比較する。OKなら後続の処 理を呼び出す スルー 例外が投げられた訳 ではないのでスルー スルー
  • 18. Security Filter Chainのログ 1/2 • どのFilterが、どの順番で動いたかをログに出力す ることが可能 – デバッグに便利 • 設定方法 – ロガーの「org.springframework.security」をDEBUGレベルに する – application.propertiesでの設定例 18 logging.level.org.springframework.security=DEBUG
  • 19. Security Filter Chainのログ 2/2 • 出力例 – 未認証のユーザが、認可が必要なURLにアクセスしたと きのログ(抜粋) 19 /admin/foo at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' /admin/foo at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' No HttpSession currently exists No SecurityContext was available from the HttpSession: null. A new one will be created. /admin/foo at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter' /admin/foo at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter' /admin/foo at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter' Request 'GET /admin/foo' doesn't match 'POST /logout' /admin/foo at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' Request 'GET /admin/foo' doesn't match 'POST /login' /admin/foo at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' saved request doesn't match /admin/foo at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' /admin/foo at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' /admin/foo at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter' /admin/foo at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' /admin/foo at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' Secure object: FilterInvocation: URL: /admin/foo; Attributes: [hasAuthority('ADMIN')] Voter: org.springframework.security.web.access.expression.WebExpressionVoter@7d30e6, returned: -1 o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point Filterの数と処理 準が表示われる 特別な処理が行われた らログにでる
  • 20. さいごに • Spring Securityの裏の動きのイメージが沸いて、デ バッグやカスタマイズの作業がし易くなれば幸いで す。 • おすすめのサイト – Spring Securityのマニュアルの「The Big Picture」の章 • https://docs.spring.io/spring- security/site/docs/current/reference/html5/#servlet- architecture 20