SlideShare une entreprise Scribd logo
1  sur  48
Télécharger pour lire hors ligne
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
これで怖くない!?
コードリーディングで学ぶ
Spring Security
(株)カサレアル 多⽥真敏
2018年11⽉30⽇
中央線Meetup #2
1
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
このセッションについて
▸ Spring Securityの認証・認可の仕組みを、

ソースコードをもとに解説します
▸ 中級者向け
▸ ライブラリのソースコードを読んだことがある⽅
▸ 認証と認可の区別がつく⽅
▸ サーブレットAPIが分かる⽅
2
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⾃⼰紹介
▸ 多⽥真敏(@suke_masa)
▸ 研修トレーナー@カサレアル
▸ Spring / Java EE / Microservices

/ Cloud Foundry
▸ Pivotal認定講師
▸ ⽇本Springユーザ会スタッフ
▸ ⽇本GlassFishユーザー会運営メンバー
3
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
Thymeleaf 3のドキュメントを(ちょっと)和訳しました!
4
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⽬次
① Spring Securityとは
② アーキテクチャをざっくり理解する
③ ソースコードを読んでより深く理解する
④ おまけ
5
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⽬次
① Spring Securityとは
② アーキテクチャをざっくり理解する
③ ソースコードを読んでより深く理解する
④ おまけ
6
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
Spring Securityとは
▸ Springのサブプロジェクト
▸ 認証・認可を中⼼に、セキュリティにまつわる様々な
機能を提供する
▸ 何重ものサーブレットフィルターで

機能を実現している
▸ 5.0でリアクティブ対応機能を

新規に開発した
7
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
Spring Securityの歴史
8
年 説明
2003 Acegi Securityとして誕⽣
2004 Apache Licenseで公開→Springに取り込まれる
2008 Spring Security 2.0としてリリース
2009 Spring Security 3.0
2015 Spring Security 4.0
2017 Spring Security 5.0
2018 Spring Security 5.1 ←今ココ
Thanks to Wikipedia
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
Spring Securityは複雑?
▸ 数あるSpringプロダクトの中でもかなり複雑な
⽅だと思います(発表者の主観)
9
⼤まかにでも内部のアーキテクチャを理解すれば
怖くなくなる・・・かも?
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⽬次
① Spring Securityとは
② アーキテクチャをざっくり理解する
③ ソースコードを読んでより深く理解する
④ おまけ
10
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
今回は
▸ 従来のサーブレット版を前提に解説します
▸ リアクティブ版は今回はスコープ外
11
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
ざっくり分かるSpring Securityアーキテクチャ
12
springSecurityFilterChain
(フィルター)
Filter
1
Filter
2
Filter
N
Authentication
Manager
(認証)
AccessDecision
Manager
(認可)
リクエスト
レスポンス
サーブ

レット
…
※本当はspringSecurityFilterChainが2つあるのですが、

 時間短縮のため省略しています
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
フィルター群
13
...
DEBUG: /login at position 1 of 12 ...: 'WebAsyncManagerIntegrationFilter'
DEBUG: /login at position 2 of 12 ...: 'SecurityContextPersistenceFilter'
DEBUG: /login at position 3 of 12 ...: 'HeaderWriterFilter'
DEBUG: /login at position 4 of 12 ...: 'CsrfFilter'
DEBUG: /login at position 5 of 12 ...: 'LogoutFilter'
DEBUG: /login at position 6 of 12 ...: 'UsernamePasswordAuthenticationFilter'
DEBUG: /login at position 7 of 12 ...: 'RequestCacheAwareFilter'
DEBUG: /login at position 8 of 12 ...: 'SecurityContextHolderAwareRequestFilter'
DEBUG: /login at position 9 of 12 ...: 'AnonymousAuthenticationFilter'
DEBUG: /login at position 10 of 12 ...: 'SessionManagementFilter'
DEBUG: /login at position 11 of 12 ...: 'ExceptionTranslationFilter'
DEBUG: /login at position 12 of 12 ...: 'FilterSecurityInterceptor'
...
▸ application.propertiesで

logging.level.org.springframework.security=debug

とするとログに出⼒される
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
重要なフィルター抜粋
14
クラス名 説明
① SecurityContext
PersistenceFilter
セッションに格納していた
SecurityContextをThreadLocalに移す
② LogoutFilter ログアウト処理を⾏う
③
UsernamePassword
AuthenticationFilter
フォーム認証を⾏う
④
ExceptionTranslation
Filter
発⽣した例外を受け取ってエラー
画⾯を表⽰する
⑤
FilterSecurity
Interceptor
アクセス制限を⾏う
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⽬次
① Spring Securityとは
② アーキテクチャをざっくり理解する
③ ソースコードを読んでより深く理解する
④ おまけ
15
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
Spring Securityコードリーディングのポイント
▸ 各フィルターから読むとよい
▸ 今回は前述のフィルター5つに絞って紹介
16
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
①SecurityContextPersistenceFilter(1/2)
17
// デフォルト実装はHttpSessionSecurityContextRepository
private SecurityContextRepository repo;
HttpRequestResponseHolder holder =
new HttpRequestResponseHolder(request, response);
// SecurityContextをHttpSessionから取り出す
SecurityContext contextBeforeChainExecution =
repo.loadContext(holder);
try {
// ThreadLocalにSecurityContextを保存する
SecurityContextHolder.setContext(contextBeforeChainExecution);
https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/
security/web/context/SecurityContextPersistenceFilter.java#L98
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
①SecurityContextPersistenceFilter(2/2)
18
// 次のフィルターに処理を委譲
chain.doFilter(holder.getRequest(), holder.getResponse());
} finally {
// リクエスト処理後のSecurityContextを取得
SecurityContext contextAfterChainExecution =
SecurityContextHolder.getContext();
// ThreadLocalからSecurityContextを削除
SecurityContextHolder.clearContext();
// HttpSessionにSecurityContextを再保存
repo.saveContext(contextAfterChainExecution,
holder.getRequest(), holder.getResponse());
}
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
なぜThreadLocalを使うのか?
▸ 実⾏中スレッドのどこからでも

SecurityContext内のユーザー情報に

アクセスできる!
19
// SecurityContextをThreadLocalから取得
SecurityContext context = SecurityContextHolder.getContext();
// 認証情報を取得
Authentication auth = context.getAuthentication();
// ログイン中のユーザー情報を取得
UserDetails userDetails = (UserDetails) auth.getPrincipal();
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
②LogoutFilter(1/2)
20
// ログアウト処理を⾏う
private final LogoutHandler handler;
// ログアウト成功後の処理を⾏う
private final LogoutSuccessHandler logoutSuccessHandler;
public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler,
LogoutHandler... handlers) {
// 複数のログアウト処理を保持するハンドラー
this.handler = new CompositeLogoutHandler(handlers);
// デフォルトではログアウト成功後、指定URLにリダイレクトする
this.logoutSuccessHandler = logoutSuccessHandler;
// ログアウトURLを"/logout"に指定
setFilterProcessesUrl("/logout");
}
https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/
security/web/authentication/logout/LogoutFilter.java#L101
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
②LogoutFilter(2/2)
21
// ログアウトURLだったら実⾏
if (requiresLogout(request, response)) {
// 認証情報を取得
Authentication auth =
SecurityContextHolder.getContext().getAuthentication();
// ログアウト処理
this.handler.logout(request, response, auth);
// ログアウト成功後の処理
logoutSuccessHandler.onLogoutSuccess(request, response, auth);
return;
}
chain.doFilter(request, response);
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
LogoutHandlerは何をしている?
▸ SecurityContextLogoutHandlerが必ず最後に実⾏される
▸ それ以外のLogoutHandlerは認証情報を利⽤可能
▸ LogoutHandlerはJava Configで追加できる
22
if (invalidateHttpSession) {
HttpSession session = request.getSession(false);
if (session != null) { session.invalidate(); }
}
if (clearAuthentication) {
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(null);
}
// SecurityContextを空にする
SecurityContextHolder.clearContext();
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
③UsernamePasswordAuthenticationFilter
23
// リクエストパラメータからユーザー名を取得
String username = obtainUsername(request);
// リクエストパラメータからパスワードを取得
String password = obtainPassword(request);
// Authenticationオブジェクトを⽣成
UsernamePasswordAuthenticationToken authRequest =
new UsernamePasswordAuthenticationToken(username, password);
setDetails(request, authRequest);
// AuthenticationManagerで認証
return this.getAuthenticationManager().authenticate(authRequest);
https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/
security/web/authentication/UsernamePasswordAuthenticationFilter.java#L75
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
AuthenticationManagerとは?
▸ 認証処理を⾏うインタフェース
▸ 実装クラスはProviderManager
▸ 実際には、AuthenticationProviderに

認証処理を委譲する
24
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
AuthenticationManagerの構造
25
<<interface>>
Authentication
Manager
ProviderManager
<<interface>>
Authentication
Provider
どれか1つで
認証成功すればOK
*
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
④ExceptionTranslationFilter(1/3)
26
try {
chain.doFilter(request, response);
// 例外をキャッチ
} catch (Exception ex) {
// 親の例外までgetCause()で辿り、全例外を配列で取得
Throwable[] causeChain =
throwableAnalyzer.determineCauseChain(ex);
// 例外の配列から、認証例外を探す
RuntimeException exception =
(AuthenticationException) throwableAnalyzer
.getFirstThrowableOfType(
AuthenticationException.class, causeChain);
https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/
security/web/access/ExceptionTranslationFilter.java#L118
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
④ExceptionTranslationFilter(2/3)
27
if (exception == null) {
// 認証例外が無ければ、認可例外を探す
exception = (AccessDeniedException) throwableAnalyzer
.getFirstThrowableOfType(
AccessDeniedException.class, causeChain);
}
if (exception != null) {
// 認証例外または認可例外を処理する
handleSpringSecurityException(
request, response, chain, exception);
} else {
// 例外をスローする
}
}
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
④ExceptionTranslationFilter(3/3)
28
private void handleSpringSecurityException(...) throws ... {
if (exception instanceof AuthenticationException) {
// ログイン画⾯にリダイレクト
} else if (exception instanceof AccessDeniedException) {
if (/* もし無名ユーザー or RememberMeだったら */) {
// ログイン画⾯にリダイレクト
} else {
// 403画⾯にフォワード
}
}
}
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
例外処理は階層がとても深い
▸ 興味がある⽅はさらにソースコードを追ってみ
てください!
29
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⑤FilterSecurityInterceptor(1/3)
30
// 前処理としてのセキュリティチェック
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
// 次のフィルターまたはサーブレットを実⾏
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
// 例外の有無に関わらず⾏うセキュリティチェック
super.finallyInvocation(token);
}
// 後処理としてのセキュリティチェック
super.afterInvocation(token, null);
https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/
security/web/access/intercept/FilterSecurityInterceptor.java#L124
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⑤FilterSecurityInterceptor(2/3)
31
protected InterceptorStatusToken beforeInvocation(Object object) {
// アクセスしたリソースに対するアクセス許可設定を取得
Collection<ConfigAttribute> attributes =
this.obtainSecurityMetadataSource().getAttributes(object);
if (SecurityContextHolder.getContext().getAuthentication()
== null) {
// 認証情報が無い旨の例外をスロー
}
// 認証処理 -> 認証情報を取得 or 認証例外をスロー
Authentication authenticated = authenticateIfRequired();
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⑤FilterSecurityInterceptor(3/3)
32
try {
// 認可処理を⾏う(NGなら例外をスロー、OKなら何もしない)
this.accessDecisionManager.decide(
authenticated, object, attributes);
} catch (AccessDeniedException accessDeniedException) {
// 認可失敗イベントを発⽕
publishEvent(new AuthorizationFailureEvent(...));
// 例外を再スロー
throw accessDeniedException;
}
// 他にもいろんな処理・・・
}
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
Filterなの?Interceptorなの?
33
<<abstract>>
AbstractSecurity
Interceptor
FilterSecurity
Interceptor
MethodSecurity
Interceptor
<<interface>>
javax.servlet.
Filter
<<interface>>
org.aopalliance.intercept.
MethodInterceptor
フィルターとして実⾏される
(URL単位の認可制御)
AOPとして実⾏される
(メソッドへの認可制御)
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
AccessDecisionManagerの構造
34
<<interface>>
AccessDecision
Manager
Affirmative
Based
(1票でもあればOK)
Consensus
Based
(多数決)
Unanimous
Based
(全会⼀致)
<<interface>>
AccessDecision
Voter
*
意思決定者
投票者
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
⽬次
① Spring Securityとは
② アーキテクチャをざっくり理解する
③ ソースコードを読んでより深く理解する
④ おまけ
35
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
kawasimaさんのQiita
36https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
kawasimaさんのQiita
37https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
kawasimaさんのQiita
38https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
kawasimaさんのQiita
39https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e
_⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈_
> 割愛させていただきます <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
40
😭
しゃーない、

⾃分で作るか・・・
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
使⽤技術
41
▸ Ninja Framework
▸ FreeMarker
▸ JPA
▸ JSR 250 (@RolesAllowed)
▸ Spring MVC (w/Spring Boot)
▸ Thymeleaf
▸ JPA
▸ Spring Security
@kawasima @suke_masa
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
基本⽅針
▸ オペレーション=URL・メソッド
▸ 各オペレーションにパーミッションを指定
42
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
URL単位のアクセス許可
43
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http.authorizeRequests()
.mvcMatchers("/signup").permitAll()
.mvcMatchers(GET, "/issues/").hasAuthority("readIssue")
.mvcMatchers(GET, "/issue/new").hasAuthority("writeIssue")
.mvcMatchers(POST, "/issues/").hasAuthority("writeIssue")
.mvcMatchers("/users").hasAuthority("manageUser")
.anyRequest().authenticated();
...
}
...
}
URLパターンごとに
パーミッションを指定
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
ビジネスロジックのアクセス許可
44
@Service
public class IssueServiceImpl implements IssueService {
...
@PreAuthorize("hasAuthority('readIssue')")
@Transactional(readOnly = true)
public List<Issue> findAll() {
return issueRepository.findAll();
}
@PreAuthorize("hasAuthority('writeIssue')")
@Transactional
public void register(Issue issue, String account) {
issueRepository.register(issue, account);
}
}
AOPでパーミッションが
チェックされる
AOPで実⾏直前に

パーミッションをチェック
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
ビュー層での権限による出し分け
45
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
...
<a href="#" class="header item">
RBAC Example
</a>
<a th:href="@{/}" sec:authorize="isAuthenticated()">
Home
</a>
<a th:href="@{/issues/}"
sec:authorize="isAuthenticated() and hasAuthority('readIssue')">
Issue
</a>
<a th:href="@{/users/}"
sec:authorize="isAuthenticated() and hasAuthority('manageUser')">
Users
</a>
...
パーミッションがある場合のみ
リンクを表⽰
(thymeleaf-extras-springsecurity5の機能)
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
ソースコード
▸ https://github.com/MasatoshiTada/rbac-
example-springsecurity
46
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
今⽇のまとめ
▸ Spring Security、なかなか複雑ですね
▸ でもコードリーディングって楽しいですね!
▸ 興味があればAuthenticationManagerや

AccessDecisionManagerも読むと⾯⽩いです
▸ RBACサンプルを作ったのでぜひ⾒てください!
47
(C) CASAREAL, Inc. All rights reserved.
#中央線Meetup
Enjoy Spring Security!!
▸ ご清聴ありがとうございました!
48

Contenu connexe

Tendances

Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Ryosuke Uchitate
 

Tendances (20)

Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組み
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
SpringBootTest入門
SpringBootTest入門SpringBootTest入門
SpringBootTest入門
 
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
 
GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢
GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢
GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
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アプリケーション
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
 
忙しい人の5分で分かるDocker 2017年春Ver
忙しい人の5分で分かるDocker 2017年春Ver忙しい人の5分で分かるDocker 2017年春Ver
忙しい人の5分で分かるDocker 2017年春Ver
 
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 ?
 
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
 
Mavenの真実とウソ
Mavenの真実とウソMavenの真実とウソ
Mavenの真実とウソ
 

Similaire à これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup

Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)
Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)
Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)
JPCERT Coordination Center
 
Cakephpstudy5 hacks jp
Cakephpstudy5 hacks jpCakephpstudy5 hacks jp
Cakephpstudy5 hacks jp
Hiroki Shimizu
 
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
kenjis
 
Jvm internal
Jvm internalJvm internal
Jvm internal
Go Tanaka
 
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 revWindows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Shotaro Suzuki
 

Similaire à これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup (20)

Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)
Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)
Apache CommonsのHttpClientに おけるSSLサーバ証明書検証不備 (CVE-2012-5783)
 
認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーション認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーション
 
Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...Building React, Flutter and Blazor development and debugging environment with...
Building React, Flutter and Blazor development and debugging environment with...
 
Google App Engineでできる、あんなこと/こんなこと
Google App Engineでできる、あんなこと/こんなことGoogle App Engineでできる、あんなこと/こんなこと
Google App Engineでできる、あんなこと/こんなこと
 
JavaScript 実践講座 Framework, Tool, Performance
JavaScript 実践講座 Framework, Tool, PerformanceJavaScript 実践講座 Framework, Tool, Performance
JavaScript 実践講座 Framework, Tool, Performance
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (JavaDayTokyo2015)
 
Use JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUse JWT access-token on Grails REST API
Use JWT access-token on Grails REST API
 
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
 
Cakephpstudy5 hacks jp
Cakephpstudy5 hacks jpCakephpstudy5 hacks jp
Cakephpstudy5 hacks jp
 
PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!
 
楽天における安全な秘匿情報管理への道のり
楽天における安全な秘匿情報管理への道のり楽天における安全な秘匿情報管理への道のり
楽天における安全な秘匿情報管理への道のり
 
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
脆弱性事例に学ぶセキュアコーディング「SSL/TLS証明書検証」編 (KOF2014)
 
Apache Axis2におけるXML署名検証不備
Apache Axis2におけるXML署名検証不備Apache Axis2におけるXML署名検証不備
Apache Axis2におけるXML署名検証不備
 
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 
Jvm internal
Jvm internalJvm internal
Jvm internal
 
Developers.IO 2018 ビジネスを阻害しない!AWS アカウントの管理
Developers.IO 2018 ビジネスを阻害しない!AWS アカウントの管理Developers.IO 2018 ビジネスを阻害しない!AWS アカウントの管理
Developers.IO 2018 ビジネスを阻害しない!AWS アカウントの管理
 
Android4.2徹底解剖!
Android4.2徹底解剖!Android4.2徹底解剖!
Android4.2徹底解剖!
 
はじめてのCodeIgniter
はじめてのCodeIgniterはじめてのCodeIgniter
はじめてのCodeIgniter
 
AzureActiveDirectoryの認証の話(Azure周りの自動化編)
AzureActiveDirectoryの認証の話(Azure周りの自動化編)AzureActiveDirectoryの認証の話(Azure周りの自動化編)
AzureActiveDirectoryの認証の話(Azure周りの自動化編)
 
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 revWindows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
 

Plus de Masatoshi Tada

ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
Masatoshi Tada
 
JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc
JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_cccJPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc
JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc
Masatoshi Tada
 

Plus de Masatoshi Tada (12)

Java EE 8新機能解説 -Bean Validation 2.0編-
Java EE 8新機能解説 -Bean Validation 2.0編-Java EE 8新機能解説 -Bean Validation 2.0編-
Java EE 8新機能解説 -Bean Validation 2.0編-
 
JSUG SpringOne 2017報告会
JSUG SpringOne 2017報告会JSUG SpringOne 2017報告会
JSUG SpringOne 2017報告会
 
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるとにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みる
 
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
 
Spring Data JPAによるデータアクセス徹底入門 #jsug
Spring Data JPAによるデータアクセス徹底入門 #jsugSpring Data JPAによるデータアクセス徹底入門 #jsug
Spring Data JPAによるデータアクセス徹底入門 #jsug
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with Thymeleaf
 
Java EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 FallJava EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 Fall
 
Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)
 
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho ltNetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
 
JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc
JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_cccJPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc
JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc
 

Dernier

Dernier (7)

Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 

これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup

  • 1. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup これで怖くない!? コードリーディングで学ぶ Spring Security (株)カサレアル 多⽥真敏 2018年11⽉30⽇ 中央線Meetup #2 1
  • 2. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup このセッションについて ▸ Spring Securityの認証・認可の仕組みを、
 ソースコードをもとに解説します ▸ 中級者向け ▸ ライブラリのソースコードを読んだことがある⽅ ▸ 認証と認可の区別がつく⽅ ▸ サーブレットAPIが分かる⽅ 2
  • 3. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⾃⼰紹介 ▸ 多⽥真敏(@suke_masa) ▸ 研修トレーナー@カサレアル ▸ Spring / Java EE / Microservices
 / Cloud Foundry ▸ Pivotal認定講師 ▸ ⽇本Springユーザ会スタッフ ▸ ⽇本GlassFishユーザー会運営メンバー 3
  • 4. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup Thymeleaf 3のドキュメントを(ちょっと)和訳しました! 4 https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html
  • 5. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⽬次 ① Spring Securityとは ② アーキテクチャをざっくり理解する ③ ソースコードを読んでより深く理解する ④ おまけ 5
  • 6. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⽬次 ① Spring Securityとは ② アーキテクチャをざっくり理解する ③ ソースコードを読んでより深く理解する ④ おまけ 6
  • 7. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup Spring Securityとは ▸ Springのサブプロジェクト ▸ 認証・認可を中⼼に、セキュリティにまつわる様々な 機能を提供する ▸ 何重ものサーブレットフィルターで
 機能を実現している ▸ 5.0でリアクティブ対応機能を
 新規に開発した 7
  • 8. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup Spring Securityの歴史 8 年 説明 2003 Acegi Securityとして誕⽣ 2004 Apache Licenseで公開→Springに取り込まれる 2008 Spring Security 2.0としてリリース 2009 Spring Security 3.0 2015 Spring Security 4.0 2017 Spring Security 5.0 2018 Spring Security 5.1 ←今ココ Thanks to Wikipedia
  • 9. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup Spring Securityは複雑? ▸ 数あるSpringプロダクトの中でもかなり複雑な ⽅だと思います(発表者の主観) 9 ⼤まかにでも内部のアーキテクチャを理解すれば 怖くなくなる・・・かも?
  • 10. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⽬次 ① Spring Securityとは ② アーキテクチャをざっくり理解する ③ ソースコードを読んでより深く理解する ④ おまけ 10
  • 11. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup 今回は ▸ 従来のサーブレット版を前提に解説します ▸ リアクティブ版は今回はスコープ外 11
  • 12. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ざっくり分かるSpring Securityアーキテクチャ 12 springSecurityFilterChain (フィルター) Filter 1 Filter 2 Filter N Authentication Manager (認証) AccessDecision Manager (認可) リクエスト レスポンス サーブ
 レット … ※本当はspringSecurityFilterChainが2つあるのですが、
  時間短縮のため省略しています
  • 13. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup フィルター群 13 ... DEBUG: /login at position 1 of 12 ...: 'WebAsyncManagerIntegrationFilter' DEBUG: /login at position 2 of 12 ...: 'SecurityContextPersistenceFilter' DEBUG: /login at position 3 of 12 ...: 'HeaderWriterFilter' DEBUG: /login at position 4 of 12 ...: 'CsrfFilter' DEBUG: /login at position 5 of 12 ...: 'LogoutFilter' DEBUG: /login at position 6 of 12 ...: 'UsernamePasswordAuthenticationFilter' DEBUG: /login at position 7 of 12 ...: 'RequestCacheAwareFilter' DEBUG: /login at position 8 of 12 ...: 'SecurityContextHolderAwareRequestFilter' DEBUG: /login at position 9 of 12 ...: 'AnonymousAuthenticationFilter' DEBUG: /login at position 10 of 12 ...: 'SessionManagementFilter' DEBUG: /login at position 11 of 12 ...: 'ExceptionTranslationFilter' DEBUG: /login at position 12 of 12 ...: 'FilterSecurityInterceptor' ... ▸ application.propertiesで
 logging.level.org.springframework.security=debug
 とするとログに出⼒される
  • 14. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup 重要なフィルター抜粋 14 クラス名 説明 ① SecurityContext PersistenceFilter セッションに格納していた SecurityContextをThreadLocalに移す ② LogoutFilter ログアウト処理を⾏う ③ UsernamePassword AuthenticationFilter フォーム認証を⾏う ④ ExceptionTranslation Filter 発⽣した例外を受け取ってエラー 画⾯を表⽰する ⑤ FilterSecurity Interceptor アクセス制限を⾏う
  • 15. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⽬次 ① Spring Securityとは ② アーキテクチャをざっくり理解する ③ ソースコードを読んでより深く理解する ④ おまけ 15
  • 16. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup Spring Securityコードリーディングのポイント ▸ 各フィルターから読むとよい ▸ 今回は前述のフィルター5つに絞って紹介 16
  • 17. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ①SecurityContextPersistenceFilter(1/2) 17 // デフォルト実装はHttpSessionSecurityContextRepository private SecurityContextRepository repo; HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response); // SecurityContextをHttpSessionから取り出す SecurityContext contextBeforeChainExecution = repo.loadContext(holder); try { // ThreadLocalにSecurityContextを保存する SecurityContextHolder.setContext(contextBeforeChainExecution); https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/ security/web/context/SecurityContextPersistenceFilter.java#L98
  • 18. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ①SecurityContextPersistenceFilter(2/2) 18 // 次のフィルターに処理を委譲 chain.doFilter(holder.getRequest(), holder.getResponse()); } finally { // リクエスト処理後のSecurityContextを取得 SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext(); // ThreadLocalからSecurityContextを削除 SecurityContextHolder.clearContext(); // HttpSessionにSecurityContextを再保存 repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse()); }
  • 19. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup なぜThreadLocalを使うのか? ▸ 実⾏中スレッドのどこからでも
 SecurityContext内のユーザー情報に
 アクセスできる! 19 // SecurityContextをThreadLocalから取得 SecurityContext context = SecurityContextHolder.getContext(); // 認証情報を取得 Authentication auth = context.getAuthentication(); // ログイン中のユーザー情報を取得 UserDetails userDetails = (UserDetails) auth.getPrincipal();
  • 20. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ②LogoutFilter(1/2) 20 // ログアウト処理を⾏う private final LogoutHandler handler; // ログアウト成功後の処理を⾏う private final LogoutSuccessHandler logoutSuccessHandler; public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler, LogoutHandler... handlers) { // 複数のログアウト処理を保持するハンドラー this.handler = new CompositeLogoutHandler(handlers); // デフォルトではログアウト成功後、指定URLにリダイレクトする this.logoutSuccessHandler = logoutSuccessHandler; // ログアウトURLを"/logout"に指定 setFilterProcessesUrl("/logout"); } https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/ security/web/authentication/logout/LogoutFilter.java#L101
  • 21. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ②LogoutFilter(2/2) 21 // ログアウトURLだったら実⾏ if (requiresLogout(request, response)) { // 認証情報を取得 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // ログアウト処理 this.handler.logout(request, response, auth); // ログアウト成功後の処理 logoutSuccessHandler.onLogoutSuccess(request, response, auth); return; } chain.doFilter(request, response);
  • 22. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup LogoutHandlerは何をしている? ▸ SecurityContextLogoutHandlerが必ず最後に実⾏される ▸ それ以外のLogoutHandlerは認証情報を利⽤可能 ▸ LogoutHandlerはJava Configで追加できる 22 if (invalidateHttpSession) { HttpSession session = request.getSession(false); if (session != null) { session.invalidate(); } } if (clearAuthentication) { SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(null); } // SecurityContextを空にする SecurityContextHolder.clearContext();
  • 23. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ③UsernamePasswordAuthenticationFilter 23 // リクエストパラメータからユーザー名を取得 String username = obtainUsername(request); // リクエストパラメータからパスワードを取得 String password = obtainPassword(request); // Authenticationオブジェクトを⽣成 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request, authRequest); // AuthenticationManagerで認証 return this.getAuthenticationManager().authenticate(authRequest); https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/ security/web/authentication/UsernamePasswordAuthenticationFilter.java#L75
  • 24. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup AuthenticationManagerとは? ▸ 認証処理を⾏うインタフェース ▸ 実装クラスはProviderManager ▸ 実際には、AuthenticationProviderに
 認証処理を委譲する 24
  • 25. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup AuthenticationManagerの構造 25 <<interface>> Authentication Manager ProviderManager <<interface>> Authentication Provider どれか1つで 認証成功すればOK *
  • 26. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ④ExceptionTranslationFilter(1/3) 26 try { chain.doFilter(request, response); // 例外をキャッチ } catch (Exception ex) { // 親の例外までgetCause()で辿り、全例外を配列で取得 Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex); // 例外の配列から、認証例外を探す RuntimeException exception = (AuthenticationException) throwableAnalyzer .getFirstThrowableOfType( AuthenticationException.class, causeChain); https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/ security/web/access/ExceptionTranslationFilter.java#L118
  • 27. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ④ExceptionTranslationFilter(2/3) 27 if (exception == null) { // 認証例外が無ければ、認可例外を探す exception = (AccessDeniedException) throwableAnalyzer .getFirstThrowableOfType( AccessDeniedException.class, causeChain); } if (exception != null) { // 認証例外または認可例外を処理する handleSpringSecurityException( request, response, chain, exception); } else { // 例外をスローする } }
  • 28. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ④ExceptionTranslationFilter(3/3) 28 private void handleSpringSecurityException(...) throws ... { if (exception instanceof AuthenticationException) { // ログイン画⾯にリダイレクト } else if (exception instanceof AccessDeniedException) { if (/* もし無名ユーザー or RememberMeだったら */) { // ログイン画⾯にリダイレクト } else { // 403画⾯にフォワード } } }
  • 29. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup 例外処理は階層がとても深い ▸ 興味がある⽅はさらにソースコードを追ってみ てください! 29
  • 30. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⑤FilterSecurityInterceptor(1/3) 30 // 前処理としてのセキュリティチェック InterceptorStatusToken token = super.beforeInvocation(fi); try { // 次のフィルターまたはサーブレットを実⾏ fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { // 例外の有無に関わらず⾏うセキュリティチェック super.finallyInvocation(token); } // 後処理としてのセキュリティチェック super.afterInvocation(token, null); https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/ security/web/access/intercept/FilterSecurityInterceptor.java#L124
  • 31. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⑤FilterSecurityInterceptor(2/3) 31 protected InterceptorStatusToken beforeInvocation(Object object) { // アクセスしたリソースに対するアクセス許可設定を取得 Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource().getAttributes(object); if (SecurityContextHolder.getContext().getAuthentication() == null) { // 認証情報が無い旨の例外をスロー } // 認証処理 -> 認証情報を取得 or 認証例外をスロー Authentication authenticated = authenticateIfRequired();
  • 32. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⑤FilterSecurityInterceptor(3/3) 32 try { // 認可処理を⾏う(NGなら例外をスロー、OKなら何もしない) this.accessDecisionManager.decide( authenticated, object, attributes); } catch (AccessDeniedException accessDeniedException) { // 認可失敗イベントを発⽕ publishEvent(new AuthorizationFailureEvent(...)); // 例外を再スロー throw accessDeniedException; } // 他にもいろんな処理・・・ }
  • 33. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup Filterなの?Interceptorなの? 33 <<abstract>> AbstractSecurity Interceptor FilterSecurity Interceptor MethodSecurity Interceptor <<interface>> javax.servlet. Filter <<interface>> org.aopalliance.intercept. MethodInterceptor フィルターとして実⾏される (URL単位の認可制御) AOPとして実⾏される (メソッドへの認可制御)
  • 34. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup AccessDecisionManagerの構造 34 <<interface>> AccessDecision Manager Affirmative Based (1票でもあればOK) Consensus Based (多数決) Unanimous Based (全会⼀致) <<interface>> AccessDecision Voter * 意思決定者 投票者
  • 35. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ⽬次 ① Spring Securityとは ② アーキテクチャをざっくり理解する ③ ソースコードを読んでより深く理解する ④ おまけ 35
  • 36. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup kawasimaさんのQiita 36https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e
  • 37. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup kawasimaさんのQiita 37https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e
  • 38. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup kawasimaさんのQiita 38https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e
  • 39. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup kawasimaさんのQiita 39https://qiita.com/kawasima/items/8dd7eda743f2fdcad78e _⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈⼈_ > 割愛させていただきます <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
  • 40. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup 40 😭 しゃーない、
 ⾃分で作るか・・・
  • 41. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup 使⽤技術 41 ▸ Ninja Framework ▸ FreeMarker ▸ JPA ▸ JSR 250 (@RolesAllowed) ▸ Spring MVC (w/Spring Boot) ▸ Thymeleaf ▸ JPA ▸ Spring Security @kawasima @suke_masa
  • 42. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup 基本⽅針 ▸ オペレーション=URL・メソッド ▸ 各オペレーションにパーミッションを指定 42
  • 43. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup URL単位のアクセス許可 43 @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { ... @Override protected void configure(HttpSecurity http) throws Exception { ... http.authorizeRequests() .mvcMatchers("/signup").permitAll() .mvcMatchers(GET, "/issues/").hasAuthority("readIssue") .mvcMatchers(GET, "/issue/new").hasAuthority("writeIssue") .mvcMatchers(POST, "/issues/").hasAuthority("writeIssue") .mvcMatchers("/users").hasAuthority("manageUser") .anyRequest().authenticated(); ... } ... } URLパターンごとに パーミッションを指定
  • 44. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ビジネスロジックのアクセス許可 44 @Service public class IssueServiceImpl implements IssueService { ... @PreAuthorize("hasAuthority('readIssue')") @Transactional(readOnly = true) public List<Issue> findAll() { return issueRepository.findAll(); } @PreAuthorize("hasAuthority('writeIssue')") @Transactional public void register(Issue issue, String account) { issueRepository.register(issue, account); } } AOPでパーミッションが チェックされる AOPで実⾏直前に
 パーミッションをチェック
  • 45. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ビュー層での権限による出し分け 45 <html xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> ... <a href="#" class="header item"> RBAC Example </a> <a th:href="@{/}" sec:authorize="isAuthenticated()"> Home </a> <a th:href="@{/issues/}" sec:authorize="isAuthenticated() and hasAuthority('readIssue')"> Issue </a> <a th:href="@{/users/}" sec:authorize="isAuthenticated() and hasAuthority('manageUser')"> Users </a> ... パーミッションがある場合のみ リンクを表⽰ (thymeleaf-extras-springsecurity5の機能)
  • 46. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup ソースコード ▸ https://github.com/MasatoshiTada/rbac- example-springsecurity 46
  • 47. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup 今⽇のまとめ ▸ Spring Security、なかなか複雑ですね ▸ でもコードリーディングって楽しいですね! ▸ 興味があればAuthenticationManagerや
 AccessDecisionManagerも読むと⾯⽩いです ▸ RBACサンプルを作ったのでぜひ⾒てください! 47
  • 48. (C) CASAREAL, Inc. All rights reserved. #中央線Meetup Enjoy Spring Security!! ▸ ご清聴ありがとうございました! 48