Spring Security6でログイン認証

# Spring Securityによるログイン認証の実装

Spring Securityは、セキュリティ対策を可能にするフレームワークであり、認証と認可の機能を提供しています。
この記事では、2つの簡単なAPIを実装した、Spring BootアプリケーションにSpring Securityを組み込み、簡単なログイン認証を実装する方法を説明します。

## 1. Spring Securityの概要

Spring Securityは、アプリケーションのセキュリティを強化するために広く使用されているフレームワークです。主な特徴は以下の通りです。

- **認証（Authentication）**: ユーザーが自分の身元を確認するプロセス
- **認可（Authorization）**: 特定のリソースへのアクセスを制御するプロセス

この記事では、Spring Securityが提供するログイン認証機能を実装します。

## 2. コントローラーの作成

まず、2つの簡単なRESTコントローラーを作成します。

### 2.1 認証・認可が不要なコントローラー

認証を必要としないエンドポイント`/allowedHello`を持つ、`AllowedController.java`を作成します。

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

@RestController
public class AllowedController {
  
  @GetMapping("/allowedHello")
  public String hello() {
    return "allowed hello";
  }
}
```

### 2.1 認証・認可が必要なコントローラー

認証が必要なエンドポイント`/Hello`を持つ、`HelloController.java`を作成します。

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

@RestController
public class HelloController {
  @GetMapping("/hello")
  public String hello() {
    return "hello";
  }
}
```

## 3. SecurityConfigファイルの作成

Spring Securityの設定を行う`SecurityConfig.java`を作成します。

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {
  @Bean
  SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
      http.authorizeHttpRequests((requests) -> requests.requestMatchers("/hello").authenticated()
                      .requestMatchers("/allowedHello").permitAll())
              .formLogin(Customizer.withDefaults())
              .httpBasic(Customizer.withDefaults());
      return http.build();
  }
}
```

### 3.1 SecurityConfigの解説

- `http.authorizeHttpRequests()`メソッドを使用して、特定のHTTPリクエストに対するセキュリティポリシーを設定します。
- `requestMatchers("/hello").authenticated()`は`/hello`パスへのアクセスに認証を要求します。
- `requestMatchers("/allowedHello").permitAll()`は`/allowedHello`パスへのアクセスを認証なしで許可します。
- `formLogin()`と`httpBasic()`メソッドで、フォームベースのログインとHTTPベーシック認証を有効にします。

## 4. Spring Securityを使用したログイン認証の確認

### 1.1 `/allowedHello`へのアクセス

まず、ブラウザから`/allowedHello`にアクセスします。このエンドポイントは認証を必要としないため、直接文字列が返ってくることが確認できます。

### 1.2 `/hello`へのアクセス

次に、`/hello`にアクセスしてください。こちらは認証が必要なため、ログイン画面が表示されます。

- **ユーザー名**: `user`
- **パスワード**: 実行時のコンソールに表示される `Using generated security password: {パスワード}` に記載されているパスワードを使用します。

ログインに成功すると、`/hello`から返される文字列が表示されることを確認できます。

### 1.3 ログアウトプロセス

`/logout`にアクセスすることで、ユーザーはログアウトすることができます。

### 1.4 セッションの維持

一度ログインすると、Spring Securityはユーザーのログイン情報を保持します。これにより、次回のアクセス時に再度ログインする必要がありません。

## 5. 最後に

このようにSpring Securityを用いることで、ウェブアプリケーションにおけるセキュアなユーザー認証とアクセス制御を簡単に実装することができます。

今回、Spring Securityのデフォルト機能を活用して、基本的なログインプロセスを実装しました。これには、Spring Securityが提供する標準的なログイン画面とデフォルトのユーザー情報を使用し、シンプルな認証プロセスを確認しました。

しかし、実際のアプリケーション開発では、より複雑でカスタマイズされたセキュリティ要件に対応する必要があります。特に以下の点は、実際の業務では必要不可欠です。

- **カスタムログイン画面の作成**: ユーザーエクスペリエンスを向上させるために、独自のログイン画面をデザインし実装します。
- **データベースを活用したユーザー認証**: 実際のユーザー情報をデータベースに格納し、これを用いて認証プロセスを行います。
- **パスワードのハッシュ化**: セキュリティを強化するために、パスワードをハッシュ化して安全に保管します。
- **トークンベースの認証**: よりセキュアな認証のために、トークン（例えばJWT）を使用します。

次回以降、上記の実装をどのように行うのか記載します。