LoginSignup
19
28

More than 1 year has passed since last update.

Spring Security 使い方メモ Spring MVC, Boot との連携

Last updated at Posted at 2017-08-02

Spring Security は 5.4 以降、設定の書き方に大幅な変更が入っています。
詳しくは @suke_masa さんの Spring Security 5.7でセキュリティ設定の書き方が大幅に変わる件 - Qiita を参照してください。

基礎・仕組み的な話
認証・認可の話
Remember-Me の話
CSRF の話
セッション管理の話
レスポンスヘッダーの話
メソッドセキュリティの話
CORS の話
Run-As の話
ACL の話
テストの話

番外編
Spring Security にできること・できないこと


Spring MVC や Spring Boot で Spring Security を使う方法とか、なんかその辺の話。

Spring MVC との連携

リクエストパスの Matcher

まずは普通に統合させてみる

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.3.RELEASE'
    compile 'org.springframework.security:spring-security-config:4.2.3.RELEASE'
    compile 'org.springframework:spring-webmvc:4.3.10.RELEASE'
}
  • 依存関係に spring-webmvc を追加
MyMvcController.java
package sample.spring.security.mvc;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyMvcController {
    
    @GetMapping("/foo")
    public String foo() {
        return "FOO!!";
    }
}
  • /foo に GET リクエストがきたら "FOO!!" と返すコントローラクラス

namespace

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">
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/mvc.xml
            /WEB-INF/security.xml
        </param-value>
    </context-param>

    <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>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>
  • Spring Security の DelegatingFilterProxy と Spring MVC の DispatcherServlet をそれぞれ定義
  • Spring MVC と Security の設定ファイルとして /WEB-INF/mvc.xml/WEB-INF/security.xml を指定
security.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="/foo" access="isAuthenticated()" />
        <sec:form-login />
    </sec:http>

    <sec:authentication-manager />
</beans>
  • Spring Security の設定
  • /foo へのアクセスは認証が必要ということにしている
mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven />
    
    <bean class="sample.spring.security.mvc.MyMvcController" />
    
</beans>
  • Spring MVC 用の設定

Java Configuration

MySecurityInitializer.java
package sample.spring.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class MySecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
  • Spring Security の Filter を適用するためのクラス
  • Spring Security 単体のときは、ここで設定クラスを親クラスのコンストラクタに渡していたが、 MVC と統合した場合は MVC 用の Initializer の方に移動している
MyServletInitializer.java
package sample.spring.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {MySecurityConfig.class, MyMvcConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {};
    }
    
    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }
}
  • Spring MVC 用の初期化クラス
  • MVC の設定(MyMvcConfig)も Security の設定(MySecurityConfig)も、両方ともアプリケーションのルートとして設定している(理由はよくわかってないが、こうしないと後述する mvcMatchers が働かなかった)
MySecurityConfig.java
package sample.spring.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/foo").authenticated()
            .and()
            .formLogin();
    }
}
  • Spring Security の設定クラス
  • /foo へのリクエストは認証が必要
MyMvcConfig.java
package sample.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import sample.spring.security.mvc.MyMvcController;

@EnableWebMvc
public class MyMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public MyMvcController myMvcController() {
        return new MyMvcController();
    }

    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        return new RequestMappingHandlerMapping();
    }
}
  • Spring MVC 用の設定
  • コントローラを登録している

動作確認

まずは /foo にリクエストを飛ばし、次に /foo.html にリクエストを飛ばす。

$ curl http://localhost:8080/namespace/foo -i
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID=0AD6574E5F43053B42E5C9926535AC0E; Path=/namespace/; HttpOnly
Location: http://localhost:8080/namespace/login
Content-Length: 0
Date: Mon, 31 Jul 2017 13:05:03 GMT


$ curl http://localhost:8080/namespace/foo.html -i
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Disposition: inline;filename=f.txt
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 5
Date: Mon, 31 Jul 2017 13:05:06 GMT

FOO!!

/foo の場合はログイン画面にリダイレクトを促されたが、 /foo.html の場合は普通にコントローラの実装が呼ばれてしまった。

なぜこうなるか

  • Spring MVC は、 /foo というパスをコントローラにマッピングしたときに、設定によっては /foo.html など拡張子を指定したパスもマッチングの対象になる
    • この挙動自体は、レスポンスの形式の切り替えを拡張子によって指定するタイプの API を簡単に実装できるようにすることが目的となっている
    • /foo.html/foo.json も同じコントローラのメソッドにマッピングされるようにしている
  • しかし、 Spring Security は Ant 形式でパスを指定しているため、 /foo 以外のパスへのリクエストはすり抜けてしまう

Spring MVC 用の RequestMatcher

  • この問題に対応するため、 Spring Security には Spring MVC のパスのマッチング処理と同じロジックでパスのマッチングを行う Matcher が用意されている

namespace

security.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 request-matcher="mvc">
        <sec:intercept-url pattern="/foo" access="isAuthenticated()" />
        <sec:form-login />
    </sec:http>

    <sec:authentication-manager />
</beans>
  • <http> タグの request-matchermvc を指定する

Java Configuration

MySecurityConfig.java
package sample.spring.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .mvcMatchers("/foo").authenticated()
            .and()
            .formLogin();
    }
}
  • antMatchers() の代わりに mvcMatchers() を使用する
動作確認
$ curl http://localhost:8080/namespace/foo -i
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID=0322DCB394ED74B38CCA600DDEF8CBBF; Path=/namespace/; HttpOnly
Location: http://localhost:8080/namespace/login
Content-Length: 0
Date: Mon, 31 Jul 2017 13:07:48 GMT


$ curl http://localhost:8080/namespace/foo.html -i
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID=BE049E9C138392A8751351762B200D63; Path=/namespace/; HttpOnly
Location: http://localhost:8080/namespace/login
Content-Length: 0
Date: Mon, 31 Jul 2017 13:07:49 GMT

今度は .html をつけてもログイン画面へ飛ばされた。

コントローラの引数で現在のプリンシパルを受け取る

実装

MyMvcController.java
package sample.spring.security.mvc;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyMvcController {
    
    @GetMapping("/user")
    public String foo(@AuthenticationPrincipal User user) {
        System.out.println("username=" + user.getUsername() + ", authorities=" + user.getAuthorities());
        return "User!!";
    }
}

namespace

mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
        </mvc:argument-resolvers>
    </mvc:annotation-driven>
    
    <bean class="sample.spring.security.mvc.MyMvcController" />
    
</beans>
security.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 request-matcher="mvc">
        <sec:intercept-url pattern="/login" access="permitAll" />
        <sec:intercept-url pattern="/**" access="isAuthenticated()" />
        <sec:form-login />
        <sec:logout />
    </sec:http>

    <sec:authentication-manager>
        <sec:authentication-provider>
            <sec:user-service>
                <sec:user name="foo" password="foo" authorities="GENERAL_USER, ADMINISTRATOR" />
            </sec:user-service>
        </sec:authentication-provider>
    </sec:authentication-manager>
</beans>

Java Configuration

MyMvcConfig.java は変更なし

MySecurityConfig.java
package sample.spring.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .mvcMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("foo")
            .password("foo")
            .authorities("GENERAL_USER", "ADMINISTRATOR");
    }
}

動作確認

ブラウザでアクセスして foo ユーザでログイン後、 /user にアクセスする。

サーバーコンソール出力
username=foo, authorities=[ADMINISTRATOR, GENERAL_USER]

説明

MyMvcController.java
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;

...

    @GetMapping("/user")
    public String foo(@AuthenticationPrincipal User user) {
        System.out.println("username=" + user.getUsername() + ", authorities=" + user.getAuthorities());
        return "User!!";
    }
  • コントローラの引数で Authentication.getPrincipal() が返すオブジェクトを受け取ることができる
  • 引数を @AuthenticationPrincipal でアノテートする
  • 引数の解決は、 Spring Security が提供する AuthenticationPrincipalArgumentResolver によって行われる
mvc.xml
    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
        </mvc:argument-resolvers>
    </mvc:annotation-driven>
  • namespace を使っている場合は、 <argument-resolvers>AuthenticationPrincipalArgumentResolver を指定してあげる必要がある
  • Java Configuration を使っている場合は、 @EnableWebSecurity を使うことでこの設定が自動的に行われるので、追加での設定は不要

CSRF トークンを受け取る

実装

MyMvcController.java
package sample.spring.security.mvc;

import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyMvcController {
    
    @GetMapping("/csrf")
    public String foo(CsrfToken token) {
        System.out.println("token=" + token.getToken() + ", headerName=" + token.getHeaderName() + ", parameterName=" + token.getParameterName());
        return "CSRF!!";
    }
}

namespace

mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver" />
        </mvc:argument-resolvers>
    </mvc:annotation-driven>
    
    <bean class="sample.spring.security.mvc.MyMvcController" />
    
</beans>
security.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 request-matcher="mvc">
        <sec:intercept-url pattern="/**" access="permitAll" />
        <sec:form-login />
        <sec:csrf />
    </sec:http>

    <sec:authentication-manager />
</beans>

Java Configuration

MyMvcConfig は変更なし

MySecurityConfig.java
package sample.spring.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .mvcMatchers("/**").permitAll()
            .and()
            .formLogin()
            .and()
            .csrf();
    }
}

実行結果

/csrf にアクセスする

サーバーコンソール出力
token=bcac7b2e-f2c0-424c-a563-4b957ff7133e, headerName=X-CSRF-TOKEN, parameterName=_csrf

説明

MyMvcController.java
import org.springframework.security.web.csrf.CsrfToken;

...
    
    @GetMapping("/csrf")
    public String foo(CsrfToken token) {
        System.out.println("token=" + token.getToken() + ", headerName=" + token.getHeaderName() + ", parameterName=" + token.getParameterName());
        return "CSRF!!";
    }
  • CSRF のトークンをコントローラのメソッド引数で受け取ることができる
  • トークンは CsrfToken インスタンスとして取得できる
mvc.xml
    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver" />
        </mvc:argument-resolvers>
    </mvc:annotation-driven>
  • namespace の場合、 CsrfToken を引数で受け取るようにするためには、 CsrfTokenArgumentResolver<argument-resolvers> で指定する必要がある
  • Java Configuration の場合は @EnableWebSecurity を使えば自動的に登録されるので、追加の設定は不要

Spring Boot との連携

Hello World

実装

build.gradle
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.6.RELEASE'
    }
}

apply plugin: 'java'
apply plugin: 'spring-boot'

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

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.boot:spring-boot-starter-security'
}
Main.java
package sample.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
src/main/resources/static/hello.html
<!doctype html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello Spring Security with Spring Boot</title>
    </head>
    <body>
        <h1>Hello Spring Security!!</h1>
    </body>
</html>

動作確認

$ gradle bootRun
The plugin id 'spring-boot' is deprecated. Please use 'org.springframework.boot' instead.
:compileJava
:processResources
:classes
:findMainClass
:bootRun

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.6.RELEASE)

2017-08-02 22:55:17.710  INFO 13608 --- [           main] sample.boot.Main                         : Starting Main on .....
 with PID 13608 (...\spring-boot-security\build\classes\main started by .... in ...\spring-boot-security)

(中略)

2017-08-02 22:55:19.756  INFO 13608 --- [           main] b.a.s.AuthenticationManagerConfiguration :

Using default security password: 40890087-600d-417d-962d-a856e139b9c4

2017-08-02 22:55:19.808  INFO 13608 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []

(後略)

http://localhost:8080/hello.html にアクセスする。

spring-boot-security.jpg

ダイアログが表示されてユーザー名とパスワードの入力を求められるので、次のように入力する。

入力項目
ユーザー名 user
パスワード 起動時にコンソールに出力されたパスワード

パスワードは、アプリケーションを起動したときにコンソールに出力されている。

コンソールに出力されたパスワード
Using default security password: 40890087-600d-417d-962d-a856e139b9c4

spring-boot-security.jpg

ログインに成功して、 hello.html の内容が表示される。

説明

build.gradle
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.boot:spring-boot-starter-security'
}
  • spring-boot-starter-security を追加すると Spring Security の依存関係が追加される
  • 何もしないと、デフォルトで Basic 認証が有効になり、 user という名前のユーザーがメモリ上に用意される(パスワードは起動しなおすと変わる)
    • パスワードは security.user.password プロパティで明示することも可能
  • また、 /js/**, /css/**, /images/**, /webjars/**, **/favicon.js へのアクセスは認証なしで可能なように設定されている

設定を明示する

実装

MySecurityConfig.java
package sample.boot.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .mvcMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("foo").password("foo").authorities("TEST_USER");
    }
}

動作確認

http://localhost:8080/hello.html にアクセス

spring-boot-security.jpg

デフォルトのログイン画面が表示されるので、 foo ユーザでログインする

spring-boot-security.jpg

説明

@EnableWebSecurity でアノテートした設定クラスを追加し、 Spring Security の設定を明示することによって、デフォルトの挙動を任意に書き換えることができる。

参考

19
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
28