【Spring MVC + Spring Security】デフォルトログイン画面を利用して認証する方法

概要

Spring Securityが提供するデフォルトのログイン画面を利用して、簡易的なログイン認証機能を利用する方法についてまとめた。

 

前提

以下の記事の続きとなる。

あわせて読みたい

概要 Spring Security機能を利用するための必要資材や導入方法についてまとめた。   前提 以下の記事の続きとなる。

 

デフォルトログイン機能

作成するログイン機能は以下のような挙動となる。

 

・未ログイン時はどのURLにアクセスしても、Spring Security提供のログイン画面にリダイレクトされる
・ログインに成功すると、トップページ画面(自作)に遷移する

 

実装

デフォルトログイン機能を実装する。
※ログイン成功後のトップページ画面表示資材については割愛

 

ログイン画面表示

ログイン画面表示に必要な設定を、SecurityFilterChain内で定義する。

 

▲認証処理と認可処理に関するフィルターを定義する

 

SecurityConfig.java


package com.example.prototype.biz.security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // HTTPリクエストの認可ルール
                .authorizeHttpRequests(auth ->
                    // すべてのリクエストは認証必須 
                    auth.anyRequest().authenticated())
                
                // Spring Securityのデフォルトログイン画面表示
                .formLogin(form ->
                    // ログイン成功後の遷移先
                    form.defaultSuccessUrl("/", true)
                );

        return http.build();
    }

    (略)
}

 

.authorizeHttpRequests(auth ->

HTTPリクエストに対する認可ルールを構成するためのメソッド。

SecurityFilterChainの中にある、ExceptionTranslationFilterなどの認可に必要なフィルター群が構成されて認可処理が有効になる。
この構成により、URLパターンやHTTPメソッドに応じて、アクセスの可否や必要なロール/権限を定義できる。

 

auth.anyRequest().authenticated())

すべてのリクエストは、まず「認証が必要」という認可ルールを設定している。
未認証の状態で任意のURLにアクセスすると、401(未認証アクセス)を通知する。

 

.formLogin(form ->

フォームログインに関する認証ルールを構成するためのメソッド。

SecurityFilterChainの中にある、UsernamePasswordAuthenticationFilterなどのフォーム認証に必要なフィルター群が構成されて認証処理が有効になる。
この構成により、401(未認証アクセス)が発生した際には「 /login」にリダイレクトを行う。
※「/login」にリダイレクトすると、Spring Securityが自動生成したログインフォーム画面が表示される

 

form.defaultSuccessUrl(“/”, true)

ログイン成功後は、常に「/」にリダイレクトするという設定。

 

以上の設定により、デフォルトのログイン画面表示とログイン後の挙動についての定義が完了となる。

 

認証対象データ取得

認証対象となるデータを取得するUserDetailsServiceをカスタマイズする。
本来はDBから認証対象データを取得するが、今回はサーバー側で一時的に認証可能となるユーザーを定義する。

 

▲本来はDBから認証対象データ(UserDetails)を取得する

 

SecurityConfig.java


package com.example.prototype.biz.security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        (略)
    }

    @Bean
    public UserDetailsService userDetailsService() {
        // 認証対象データを仮で用意
        UserDetails user = User
                .withUsername("user")
                .password("{noop}password")
                .roles("USER").build();
        
        return new InMemoryUserDetailsManager(user);
    }
}

 

@Bean
public UserDetailsService userDetailsService() {

UserDetailsServiceをカスタマイズするためにBean定義する。

 

UserDetails user = User

認証対象の仮ユーザー情報を定義している。

 

.password(“{noop}password”)

「{noop}」はパスワードが暗号化されていないことを表す記号。

 

.roles(“USER”)

ログインユーザーに対して、仮で「ROLE_USER」という役割を付与している。
※Spring Securityでは、roles()に指定した値に”ROLE_”というプリフィックスを自動的に付与する

本来はDBから認証対象のデータを取得してUserDetailsに格納して画面入力情報と突合するが、
今回は上記の設定により、「user」と「password」が画面入力されることで認証成功となる。

※他にも以下のような定義が可能

.credentialsExpired(true) // パスワード期限切れ
.disabled(true) // アカウント無効
.accountLocked(true) // ロック中

 

 

動作確認

ログイン認証を行う。
「http:localhost:8080/コンテキストパス/」 + 適当なパス でリクエストを行う。

 

▲認可機能が働き、Spring Security提供のデフォルトログイン画面にリダイレクト(/login)される

 

▲「user」「password」を入力してログインする

 

▲認証に成功した場合、「/」にリダイレクトされる

 

▲「user」「password」以外を入力した場合、上記のようにエラー内容に応じたメッセージが表示される

 

 

まとめ

 

☑ Spring Securityでは、SecurityFilterChain内で認証・認可についてのフィルター機能を定義する

☑ ログイン検証はUserDetailsService内に仮ユーザーを定義することで、簡易的に確認可能となる

☑ デフォルトのログイン画面を使用すると、エラーメッセージ表示が自動で処理される

 

スポンサーリンク