Posted at

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

More than 1 year has passed since last update.

基礎・仕組み的な話

認証・認可の話

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 の設定を明示することによって、デフォルトの挙動を任意に書き換えることができる。


参考