Help us understand the problem. What is going on with this article?

Hello World で学ぶ Spring Security の仕組み

More than 1 year has passed since last update.

Hello World で学ぶ Spring Security の仕組み

by opengl-8080
1 / 54

自己紹介

  • opengl-8080
  • 主に Qiita で技術メモを書いたり
  • 関西の SIer 勤務

今日お話しすること

簡単な Hello World を通じて、 Spring Security の仕組みの基礎的な部分を説明

  • どのようなクラスが、どのように連携しあっているのか
  • 設定ファイルがどのように関係しているのか

背景

  • 個人的に Spring Security の勉強を開始
  • ちょっと Hello World を書こうとしたが手こずる
    • この設定はなんで必要?
    • ・・・と書くとなぜ~~~が有効に?
    • この設定って最小限の Hello World で必要?

抽象化された設定

  • Spring Security の設定は高度に抽象化されている
  • 設定が簡潔になる一方で、裏で何が行われているかが分かりづらい
  • 仕組みの理解や、カスタマイズがしづらくなる

※個人の所感です


対象者

Hello World を通じて Spring Security の仕組みを学ぶことで、

  • Spring Security をこれから勉強する人の参考に(なれるように)
  • 仕組みを知らずに Spring Security を使ってた人の参考に(なれるように)

前提知識

  • Servlet, JSP について、そこそこの知識を持っている
    • Filter などを知っており、 web.xml を書いて Servlet アプリを構築できる
  • Spring についてそこそこの知識を持っている
    • DI コンテナが何なのか、 Bean や AOP を理解している

Hello World アプリ(前提)

Spring Boot は使わない

  • Spring Security の基礎を学ぶのが目的
  • 素の Spring Security だけを使う

Java Config は使わない

  • xml で設定を記述する
  • 結局 Java Config もやってることは同じ

Servlet 3.0 の機能は使わない

  • Servlet 3.0 の機能を利用すれば web.xml なしで設定が可能
  • 仕組みの基礎を学ぶのが目的なので、こちらもやはり使わないようにする

Hello World アプリ(環境構築)

ソース

https://github.com/opengl-8080/spring-security-hello-world

動作確認環境

  • Java 1.8.0_121
  • Tomcat 8.0.35

war ファイルの入手

  • こちら から spring-security.war をダウンロード
  • ソースからビルドする場合は、ソースをダウンロードしてプロジェクトのルートで gradlew war を実行。

動作確認

  • Tomcat に spring-security.war をデプロイ
  • http://localhost:8080/spring-security にアクセス

Hello World アプリ(動作)

http://localhost:8080/spring-security にアクセス

spring-security.jpg

User, Password に foo と入力してログイン

spring-security.jpg

403 エラーになる

次は bar でログイン

spring-security.jpg

spring-security.jpg

index ページが表示される。

logout ボタンをクリックすればログアウトができる。


Hello World アプリ(実装内容)

ファイル構成
|-build.gradle : Gradle のビルドファイル
|
`-src/main/webapp/
  |
  |-index.jsp : インデックスページ
  |
  `-WEB-INF/
    |
    |-applicationContext.xml : Spring 設定ファイル
    |
    `-web.xml : Servlet 設定ファイル
  • 全4ファイル
    • 1つはビルドファイルなので、実際デプロイされるのは3ファイル
  • Java ソース一切なしの超シンプル構成
build.gradle
apply plugin: 'war'

sourceCompatibility = '1.8'
targetCompatibility = '1.8'
compileJava.options.encoding = 'UTF-8'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.springframework.security:spring-security-web:4.2.1.RELEASE'
    compile 'org.springframework.security:spring-security-config:4.2.1.RELEASE'
}

war.baseName = 'spring-security'

task wrapper(type: Wrapper) {
    gradleVersion = '3.2.1'
}
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>
      Hello Spring Security!!
    </title>
  </head>
  <body>
    <h1>
      Hello Spring Security!!
    </h1>

    <form action="logout" method="post">
      <input type="submit"
             value="logout" />
      <input type="hidden"
             name="${_csrf.parameterName}"
             value="${_csrf.token}" />
    </form>
  </body>
</html>
  • ログイン後に表示されるトップページ
  • メッセージとログアウトボタンがあるだけ
  • _csrf についてはデフォルトで有効になっているため設定していますが、この後の説明では特に登場しないので詳細な説明は省きます
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>

  <filter>
    <filter-name>
      springSecurityFilterChain
    </filter-name>
    <filter-class>
      org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
  </filter>

  <filter-mapping>
    <filter-name>
      springSecurityFilterChain
    </filter-name>
    <url-pattern>
      /*
    </url-pattern>
  </filter-mapping>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:sec="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/security
         http://www.springframework.org/schema/security/spring-security.xsd">

  <sec:http>
    <sec:intercept-url
            pattern="/login"
            access="permitAll" />
    <sec:intercept-url
            pattern="/**"
            access="isAuthenticated() and hasAuthority('BAR')" />
    <sec:form-login />
    <sec:logout />
  </sec:http>

  <sec:authentication-manager>
    <sec:authentication-provider>
      <sec:user-service>
        <sec:user name="foo"
                  password="foo"
                  authorities="" />
        <sec:user name="bar"
                  password="bar"
                  authorities="BAR" />
      </sec:user-service>
    </sec:authentication-provider>
  </sec:authentication-manager>
</beans>

Hello World を読み解く

  1. サーバー起動~リクエスト受付
  2. Spring Security の入り口
  3. ログイン処理
  4. アクセス制御
  5. ログアウト処理

Hello World を読み解く

  1. サーバー起動~リクエスト受付
  2. Spring Security の入り口
  3. ログイン処理
  4. アクセス制御
  5. ログアウト処理

Spring コンテナの初期化

web.xml
<listener>
  <listener-class>
    org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>
  • <listener>
    • Servlet の機能で、アプリケーション起動時に実行する処理を定義できる
  • ContextLoaderListener
    • Spring コンテナを初期化するクラス
    • デフォルトで XmlWebApplicationContext が使用される
    • 設定ファイルとして WEB-INF/applicationContext.xml が使用される

DelegatingFilterProxy の登録

web.xml
  <filter>
    <filter-name>
      springSecurityFilterChain
    </filter-name>
    <filter-class>
      org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
  </filter>

  <filter-mapping>
    <filter-name>
      springSecurityFilterChain
    </filter-name>
    <url-pattern>
      /*
    </url-pattern>
  </filter-mapping>
  • DelegatingFilterProxy という Filter を springSecurityFilterChain という名前で登録
    • Filter は Servlet の提供する機能
    • リクエストの前後に任意の処理を挟むことができる
  • url-pattern/* を指定して、全てのリクエストを処理

DelegatingFilterProxy の役割

DelegatingFilterProxyの役割.png

  • DelegatingFilterProxy は、 Spring コンテナから次の条件に一致する Bean を検索する
    • Bean の名前が自身の Filter 名(springSecurityFilterChain)と一致する
    • javax.servlet.Filter インターフェースを実装している
  • 取得した Bean に処理を委譲する
  • DelegatingFilterProxy が処理を委譲したクラスは Spring コンテナから取得した Bean なので、 Spring コンテナの機能を利用することができる
    • DI
    • AOP
    • etc...
  • DelegatingFilterProxy の役割は、 Servlet コンテナと Spring コンテナの橋渡し

Spring Security の設定

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:sec="http://www.springframework.org/schema/security"
       ...>

  <sec:http>
    <sec:intercept-url
            pattern="/login"
            access="permitAll" />
    <sec:intercept-url
            pattern="/**"
            access="isAuthenticated() and hasAuthority('BAR')" />
    <sec:form-login />
    <sec:logout />
  </sec:http>

  ...
  • applicationContext.xml は Spring の設定ファイル
    • <bean> タグを使って Bean を定義する
    • Spring Security 専用の設定ファイルというわけではない
  • Spring Security の設定を簡潔に記述できるようにするため、専用のタグが用意されている
    • リファレンスでは namespace と呼んでいる
    • xmlns:sec で読み込んでいる

<http> が肝

applicationContext.xml
  <sec:http>
    ...
  </sec:http>
  • この <http> が Spring Security の設定の肝
  • 重要な Bean が大量に登録される

FilterChainProxy

  • <http> タグが登録する Bean の1つ
  • Filter インターフェースを継承している
  • springSecurityFilterChain という名前で Spring コンテナに登録される
  • DelegatingFilterProxy が委譲する Bean の正体

まとめ (サーバー起動~リクエスト受付)

test

  1. サーブレットコンテナが起動し、 web.xmlListener として登録されている ContextLoaderListener が実行される。
  2. XmlWebApplicationContext のインスタンスが生成され、 /WEB-INF/applicationContext.xml が読み込まれる。
  3. <http> タグによって FilterChainProxy のインスタンスが "springSecurityFilterChain" という名前で Spring コンテナに登録される。
  4. web.xmlFilter として登録されている DelegateFilterProxy が、サーブレットコンテナによって生成される。
  5. リクエストがあると、 DelegateFilterProxy が呼ばれ、自身の名前("springSecurityFilterChain")で Spring コンテナから Bean を取得する(FilterChainProxy が取得される)。
  6. FilterChainProxy に処理が委譲される。

※分かりやすさ優先のため厳密には正しくないところもあります。雰囲気で見てください。


Hello World を読み解く

  1. サーバー起動~リクエスト受付
  2. Spring Security の入り口
  3. ログイン処理
  4. アクセス制御
  5. ログアウト処理

SecurityFilterChain

  • <http> が登録する重要なクラスの1つ
  • 名前の通り、 Filter を Chain (連鎖)させている
  • FilterChainProxy は、受け取ったリクエストを SecurityFilterChain が持つ Filter 達に委譲する
  • デフォルトで登録される Filter の例
    • SecurityContextPersistenceFilter
    • CsrfFilter
    • AnonymousAuthenticationFilter
    • ExceptionTranslationFilter
    • FilterSecurityInterceptor
    • etc...

Spring Security と Filter

SpringSecurityとFilter.jpg

  • Spring Security は Filter の組み合わせで実現されている
  • 機能ごとに Filter が用意されており、その FilterSecurityFilterChain に登録するかどうかで機能の有効・無効を切り替えられる

URL パターンごとの SecurityFilterChain

patternごとのSecurityFilterChain.jpg

  • SecurityFilterChain は URL パターン単位で定義することができる
    • /api/** にマッチする URL へのアクセスの場合は REST API 用に設定した SecurityFilterChain を、
    • それ以外の URL (/**) へのアクセスは、通常の画面アクセス用に設定した SecurityFilterChain を使用する
    • といったことができる
  • 例えば、「Form ログイン」のような機能は REST API でのアクセスでは不要になる

設定ファイルは次のようになる。

applicationContext.xml
  <sec:http pattern="/api/**">
    ...
  </sec:http>

  <sec:http pattern="/**">
    ...
  </sec:http>
  • <http> タグの pattern 属性で指定する
    (Ant 形式で指定できる)
  • 設定は上から順番に適用されるので、より限定的な設定をしているものを上に持ってくる
    /** の設定が /api/** より上にあると、 /api/** へのアクセスが先に /** の設定にマッチしてしまう)

まとめ (Spring Security の入り口)

  • <http> は、 SecurityFilterChain を Bean として登録する
  • SecurityFilterChain は、複数の Filter を保持している
  • Spring Security は、機能ごとに Filter が用意されている
  • Filter を組み合わせることで、必要な機能だけを持つ SecurityFilterChain を定義できる
  • SecurityFilterChain は URL パターン単位で定義できるので、
    • REST API 用の SecurityFilterChain
    • 通常の画面アクセス用の SecurityFilterChain
      という設定ができる

patternごとのSecurityFilterChain.jpg


Hello World を読み解く

  1. サーバー起動~リクエスト受付
  2. Spring Security の入り口
  3. ログイン処理
  4. アクセス制御
  5. ログアウト処理

Form ログインの有効化

applicationContext.xml
  <sec:http>
    ...
    <sec:form-login />
    ...
  </sec:http>
  • <form-login> タグを追加すると、 Form ログインが有効になる
  • Form ログインで必要になる FilterSecurityFilterChain に追加される

デフォルトのログインページ

spring-security.jpg

  • <form-login>login-page 属性が指定されていない場合、 DefaultLoginPageGeneratingFilter という Filter が登録される
  • /login に GET メソッドのリクエストがあると簡易なログインページを生成して返す
  • 動作確認をサクッと試したい場合に便利
    • Remember-Me 認証を有効にしたら自動的に Remember-Me 用のチェックボックスが追加されたりする

ログインリクエストの処理

  • ログイン処理は UsernamePasswordAuthenticationFilter という Filter によって行われる
  • /login に POST メソッドによるリクエストがくると、認証処理を開始する
  • ただし、実際の認証処理は AuthenticationManager に委譲する

AuthenticationManagerに委譲.png

ここから「委譲」がたくさん出てきてややこしいので注意!


AuthenticationManager

applicationContext.xml
  <sec:authentication-manager><sec:authentication-provider>
      <sec:user-service>
        <sec:user name="foo" ... />
        <sec:user name="bar" ... />
      </sec:user-service>
    </sec:authentication-provider>
  </sec:authentication-manager>
  • <authentication-manager> タグを宣言することで、 AuthenticationManager の実装クラスである ProviderManager が Spring コンテナに登録される
  • 認証処理の入り口となるクラス
  • ただし、 ProviderManager 自身は認証処理は行わず、 AuthenticationProvider委譲する

ProviderManagerとAuthenticationProvider.png


ProviderManager と AuthenticationProvider

AuthenticationProviderの実装クラス達.png

  • AuthenticationProvider は、認証の種類ごとに多くの実装クラスが存在している
  • ProviderManager はアプリケーションがサポートする認証方式に従い、複数の AuthenticationProvider のインスタンスを保持している
  • それぞれの AuthenticationProvider に対して、現在の認証リクエストがサポート対象かどうかを判断させ、サポートしている場合に AuthenticationProvider による認証処理が行われる
  • ProviderManager は、複数の AuthenticationProvider をまとめあげ管理する役割を担っている(まさに ProviderManager

パスワード認証を行う AuthenticationProvider

applicationContext.xml
  <sec:authentication-manager>
    <sec:authentication-provider><sec:user-service>
        <sec:user name="foo" ... />
        <sec:user name="bar" ... />
      </sec:user-service>
    </sec:authentication-provider>
  </sec:authentication-manager>
  • <authentication-provider> タグを使用することで、 DaoAuthenticationProvider というクラスが AuthenticationProvider の実装として登録される
  • DaoAuthenticationProvider は、ユーザー名とパスワードの組み合わせを使った認証処理を行う
  • その際、ユーザー情報の取得に Dao (Data Access Object) を使用する
  • Dao に当たる部分は、 UserDetailsService委譲する

UserDetailsServiceに委譲.png


UserDetailsService

UserDetailsService
public interface UserDetailsService {

    UserDetails
        loadUserByUsername(String username)
            throws UsernameNotFoundException;
}
  • ユーザー名をもとにユーザー情報(UserDetails)を返すメソッドを持つ
  • ユーザーが見つからなかった場合は UsernameNotFoundException をスローする
  • Spring Security にはこのインターフェースを実装したクラスがいくつか用意されている

InMemoryUserDetailsManager

メモリ内にユーザー情報を保存しておく実装

JdbcUserDetailsManager

JDBC 経由でデータベースからユーザー情報を検索してくる実装


InMemoryUserDetailsManager を使用する

applicationContext.xml
  <sec:authentication-manager>
    <sec:authentication-provider>
      <sec:user-service><sec:user name="foo" ... />
        <sec:user name="bar" ... />
      </sec:user-service>
    </sec:authentication-provider>
  </sec:authentication-manager>
  • <user-service> タグを使用すると、 UserDetailsService の実装として InMemoryUserDetailsManager が Spring コンテナに登録される

UserDetails

UserDetails.java
public interface UserDetails extends Serializable {

    String getUsername();
    String getPassword();
    Collection<? extends GrantedAuthority>
        getAuthorities();

    boolean isAccountNonExpired();
    boolean isAccountNonLocked();
    boolean isCredentialsNonExpired();
    boolean isEnabled();
}
  • UserDetails は、ログインユーザーの詳細情報を提供するインターフェース
  • ユーザー名やパスワード、付与された権限のコレクション、期限切れやロックなどの状態を取得できる
  • このインターフェースを実装したクラスとして、 User というクラスが用意されている

User を使用する

applicationContext.xml
  <sec:authentication-manager>
    <sec:authentication-provider>
      <sec:user-service>
        <sec:user name="foo" ... /><sec:user name="bar" ... /></sec:user-service>
    </sec:authentication-provider>
  </sec:authentication-manager>
  • <user> タグを使用すると、 User クラスを使ってユーザー情報が生成される
  • 生成されたユーザー情報は、 <user-service> すなわち InMemoryUserDetailsManager に保存される

ここまでの流れを整理

ログイン処理整理.png

  1. /login に POST リクエストがくると、 UsernamePasswordAuthenticationFilter が認証処理を行う
  2. 認証処理は AuthenticationManager に委譲される
  3. AuthenticationManager の実装クラスである ProviderManager は、所有する AuthenticationProvider に認証処理を委譲する
  4. <authentication-provider> タグで登録された DaoAuthenticationProvider は、ユーザー名とパスワードをもとに認証処理を行う
  5. その際、ユーザー情報の検索は UserDetailsService に委譲する
  6. <user-service> タグで登録された InMemoryUserDetailsManager は、 <user> タグで定義されたユーザー情報(UserDetails)をメモリ上に保存している

上記の関係性が、下の設定に込められている。

applicationContext.xml
  <sec:authentication-manager>
    <sec:authentication-provider>
      <sec:user-service>
        <sec:user name="foo" ... />
        <sec:user name="bar" ... />
      </sec:user-service>
    </sec:authentication-provider>
  </sec:authentication-manager>

認証に成功したら

AuthenticationProvider.java
public interface AuthenticationProvider {

    Authentication authenticate(Authentication authentication)
        throws AuthenticationException;
}
  • AuthenticationProvider の認証処理が成功すると、ログインしたユーザーの情報を保持した Authentication オブジェクトが返却される
  • この Authentication オブジェクトはセッションに保存され、次回以降のリクエストなどで参照されるようになる

まとめ (ログイン処理)

  • <form-login> で Form 認証が有効になる
  • UsernamePasswordAuthenticationFilter が追加され、認証処理を開始する
  • AuthenticationManager は認証処理を制御する
  • AuthenticationProvider が具体的な認証処理を行う
  • UserDetailsService はユーザー情報を検索する Dao
  • UserDetails はユーザーの詳細情報を提供する
  • 認証に成功すると、 Authentication オブジェクトがセッションに保存される

Hello World を読み解く

  1. サーバー起動~リクエスト受付
  2. Spring Security の入り口
  3. ログイン処理
  4. アクセス制御
  5. ログアウト処理

FilterSecurityInterceptor

  • <http> タグを定義することで追加される重要な Filter の1つ
  • セキュアオブジェクトの処理を実行する前後に処理を挟む
  • HTTP リクエストに関するアクセス制御は、この FilterSecurityInterceptor の中で開始される

セキュアオブジェクト

  • セキュリティ保護対象 のことを、 Spring Security のリファレンスでは セキュアオブジェクト(Secure Object) と呼んでいる
  • 「Object」とあるが、特定の Java オブジェクトのことではなく、「対象」という本来の Object の意味で使われている(たぶん)
  • 「特定の URL への HTTP リクエスト」や「メソッドの実行」などがセキュアオブジェクトにあたる

アクセス制御の委譲

AccessDecisionManagerに委譲.png

  • FilterSecurityInterceptor 自身はアクセス制御についてのチェックは行わない
  • アクセス制御の判定は AccessDecisionManager に委譲する

投票によるアクセス制御

投票によるアクセス制御

  • Spring Security が提供する AccessDecisionManager の実装クラスは、「投票」によってアクセス制御を行う
  • AccessDecisionManagerAccessDecisionVoter にアクセスの可否を投票させる
    • 付与:アクセス可
    • 拒否:アクセス不可
    • 棄権:サポート対象外
  • AccessDecisionManager は、投票結果を集計して結論を出す
    • 可の場合は何もしない
    • 不可の場合は AccessDeniedException をスローする

AccessDecisionManager の実装クラス

AccessDecisionManagerと実装クラス.png

  • AccessDecisionManager には実装クラスが3つ用意されている
  • AffirmativeBased
    • 「付与」が1つでもあればアクセス可
    • デフォルトはこのクラスが使用される
  • ConsensusBased
    • 「拒否」<「付与」の場合はアクセス可
  • UnanimousBased
    • 全て「付与」の場合はアクセス可

式ベースのアクセス制御

applicationContext.xml
  <sec:http>
    <sec:intercept-url
            pattern="/login"
            access="permitAll" />
    <sec:intercept-url
            pattern="/**"
            access="isAuthenticated() and hasAuthority('BAR')" />
    ...
  </sec:http>
  • AccessDecisionVoter の実装には、デフォルトでは WebExpressionVoter が使用される
  • Expression すなわち式ベースでアクセス可否を制御する
  • アクセス制御の式は <intercept-url> タグの access 属性で指定する
  • pattern 属性には、その制御を適用する URL のパターンを指定する

Spring Expression Language (SpEL)

applicationContext.xml
  access="permitAll"
  access="isAuthenticated() and hasAuthority('BAR')"
  • アクセス制御の式には Spring Expression Language という Spring 独自の式言語を使用する
  • 式を評価した結果が boolean になるようにする
    • true ならアクセス可
    • false ならアクセス不可
  • Spring Security 用に関数や定数が拡張されている
    • permitAll:常に true
    • isAuthenticated():認証済みなら true
    • hasAuthority():指定した権限を持っていれば true

まとめ (アクセス制御)

  • FilterSecurityInterceptor でアクセス制御が開始される
  • 実際の制御は AccessDecisionManager が行う
  • 標準の実装は「投票」によってアクセス可否を判定している
  • AccessDecisionVoter が投票を行い、 AccessDecisionManager が投票結果を集計し結論を出す
  • デフォルトでは WebExpressionVoter による SpEL を利用した式ベースのアクセス制御が有効になっている

Hello World を読み解く

  1. サーバー起動~リクエスト受付
  2. Spring Security の入り口
  3. ログイン処理
  4. アクセス制御
  5. ログアウト処理

ログアウトを有効にする

applicationContext.xml
  <sec:http>
    ...
    <sec:logout />
  </sec:http>
  • <logout> タグを使用すると、 LogoutFilter が追加される
  • /logout に POST リクエストがくると、 LogoutFilter がログアウトの処理を行う

全体ふりかえり

サーバー起動~リクエスト受付

test

Spring Security の入り口

SpringSecurityとFilter.jpg

ログイン処理

ログイン処理整理.png

アクセス制御

投票によるアクセス制御


これだけの意味がこの設定に込められている

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>

  <filter>
    <filter-name>
      springSecurityFilterChain
    </filter-name>
    <filter-class>
      org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
  </filter>

  <filter-mapping>
    <filter-name>
      springSecurityFilterChain
    </filter-name>
    <url-pattern>
      /*
    </url-pattern>
  </filter-mapping>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:sec="http://www.springframework.org/schema/security"
       ...>

  <sec:http>
    <sec:intercept-url
            pattern="/login"
            access="permitAll" />
    <sec:intercept-url
            pattern="/**"
            access="isAuthenticated() and hasAuthority('BAR')" />
    <sec:form-login />
    <sec:logout />
  </sec:http>

  <sec:authentication-manager>
    <sec:authentication-provider>
      <sec:user-service>
        <sec:user name="foo"
                  password="foo"
                  authorities="" />
        <sec:user name="bar"
                  password="bar"
                  authorities="BAR" />
      </sec:user-service>
    </sec:authentication-provider>
  </sec:authentication-manager>
</beans>

いかがでしたでしょうか?
Spring Security 簡単そうと思いました?


【悲報】まだ Hello World


今日話していない機能とか要素とか

  • GrantedAuthority
  • Role の階層化
  • メソッドのセキュリティ
  • CSRF
  • Memember-Me
  • パスワードエンコード
  • 各種カスタマイズ方法
  • テスト
  • etc...

でも、今日の話が知識の下地としてできていれば
乗り越えられるはず(たぶん)


以上

opengl-8080
ただのSE。Java好き。
tis
創業40年超のSIerです。
https://www.tis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした