iT邦幫忙

2025 iThome 鐵人賽

DAY 4
0

前言

昨天我們已經介紹過 Basic Authentication 的概念:每次請求都把帳號密碼透過 Base64 編碼放進 Authorization Header。

今天我們就用 Spring Boot Security 來實際示範一次,看看它在程式裡要怎麼設定,以及怎麼用 Postman 測試。

這是我們這系列第一次使用到Eclispe,並且使用Spring boot Security的依賴,這邊如果不了解的,可以參考我之前寫的這份文章

Day7 JPA介紹與Repository實作

大家可以直接去Clone第四天的專案來測試,這是我在第四天使用到的所有程式碼。

Git hub 程式碼:spring-security-30days day04

如果想要自己從新建立這份專案的,會推薦大家先了解如何創建Spring boot專案,並且如何注入POM依賴,學會之後就在POM中增加Spring boot Security跟Web的依賴。

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	<dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-security</artifactId>
	</dependency>

Step 1. 建立 Controller

前面都沒問題後,我們要先開始寫一個簡單的 BasicAuthController,這個的目的是建立一個API,將不同的API設定登入權限,讓我們可以實作。

package com.ansathsean.security;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

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

import jakarta.servlet.http.HttpServletRequest;

@RestController
public class BasicAuthController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, you are authenticated!";
    }

    @GetMapping("/manual-basic-auth")
    public String checkAuth(HttpServletRequest request) {
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Basic ")) {
            String base64Credentials = authHeader.substring("Basic ".length());
            String credentials = new String(Base64.getDecoder().decode(base64Credentials), StandardCharsets.UTF_8);

            // credentials = "username:password"
            String[] values = credentials.split(":", 2);
            String username = values[0];
            String password = values[1];

            if ("ithome".equals(username) && "secret".equals(password)) {
                return "Manual auth success!";
            }
        }
        return "Unauthorized";
    }
}

這裡我做了兩個 API:

  1. /hello → 測試 Spring Security 的 Basic Auth 功能。
  2. /manual-basic-auth → 手動解析 Authorization Header,展示 Basic Auth 的運作原理。

Step 2. 設定 SecurityConfig

接著我們要在 Spring Security 裡設定 Basic Auth,這樣 Spring Security 會自動幫我們攔截請求並驗證。當我們使用SecurityConfig後,我們就可以簡化程式流程,更加靈活的設定我們的授權與權限。

package com.ansathsean.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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
                User.withUsername("ithome")
                        .password("{noop}secret") // {noop} 表示不加密
                        .roles("USER")
                        .build()
        );
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // 為了測試方便,先關閉 CSRF
            .authorizeHttpRequests(auth -> auth
                    .anyRequest().authenticated()
            )
            .httpBasic(withDefaults()); // 啟用 Basic Authentication

        return http.build();
    }
}

這段設定做了幾件事:

  1. 建立一個記憶體內的使用者:ithome / secret
  2. 關閉 CSRF(測試時常會干擾 POST / PUT API)。
  3. 所有 API 都需要驗證。
  4. 啟用 Basic Authentication。
  5. 自己設定了一組帳號密碼,寫在Config中。這個情況只有在測試的時候才會這麼作。

Step 3. 使用 Postman 測試

啟動 Spring Boot 專案。

https://ithelp.ithome.com.tw/upload/images/20250913/20152864cwhubwkd5H.png

接下來我們可以用 Postman 測試:

  1. 請求 GET http://localhost:8080/hello
    • 如果沒有帶帳號密碼 → 會得到 401 Unauthorized

https://ithelp.ithome.com.tw/upload/images/20250913/20152864Bl4zmlN844.png

  • 如果輸入 ithome / secret → 會回傳:

      ```
      Hello, you are authenticated!
      ```
    

https://ithelp.ithome.com.tw/upload/images/20250913/20152864AcnCDjhHFa.png

測時成功後,接下來我們可以來測試另一個,不靠Spring boot Security,靠我們自己寫程式來驗證的方式,可以看到我們需要寫得非常長,內容就變得非常多。

  1. 請求 GET http://localhost:8080/manual-basic-auth

    • 在 Header 加入:

      Authorization: Basic aXRob21lOnNlY3JldA==
      

      (這個Basic後面就是ithome:secret 經過 Base64 編碼)

    • 當我們成功後就能看到回應:

    Manual auth success!
    

https://ithelp.ithome.com.tw/upload/images/20250913/20152864dK8zhIQYB7.png

Basic Authentication缺點

恭喜大家在今天成功實作了 Basic Authentication!

但它有幾個致命問題:

  1. 帳號密碼每次都會被傳送 → 不安全。
  2. 沒有 Session 概念 → 無法「登出」。
  3. 密碼只用 Base64 編碼 → 很容易被解碼。

因此,Basic Auth 幾乎不會在正式專案中使用,頂多在測試環境、短期驗證 API或是內部系統中使用

總結

今天我們透過 Spring Boot Security 成功實作了 Basic Authentication

  • 建立使用者 → ithome / secret
  • 寫 Controller 測試 Basic Auth
  • 用 Postman 驗證帳號密碼是否正確

雖然它運作簡單,但安全性不足,因此我們會在接下來的章節,介紹更安全、更進階的做法:Cookie Based Authentication

簡單來說,就是不一直給密碼,而是驗證之後給你一張門票,當你重新登入的時候就使用這張門票。

明天我們要進一步學習 Cookie 與 Session 的登入機制,看看伺服器是怎麼「記住」使用者狀態的。

夕陽依舊那麼~美麗,明天還是要po文~


上一篇
Day 3 Basic Authentication (概念篇)
下一篇
Day 5 Cookie Based Authentication (Session 機制)
系列文
「站住 口令 誰」關於資安權限與授權的觀念教學,以Spring boot Security框架實作5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言