iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Software Development

我的SpringBoot絕學:7+2個專案,從新手變專家系列 第 13

Day13 第五個Spring Boot專案:會員註冊登入系統(3)登入、Spring Security設定

  • 分享至 

  • xImage
  •  

顯示註冊用戶

我們接下來要編寫顯示全體用戶的email的頁面,之後會作為登入後才能查看的頁面,這部分大家應該都很熟悉了,可以參考第四個專案。

//UserService.java
public List<User> getAllUsers() {
        return userRepository.findAll();
    }
//AuthController.java
//顯示全體用戶email的網頁
    @GetMapping("/users")
    public String users(Model model) {
        List<User> users = userService.getAllUsers();
        model.addAttribute("users", users);
        return "users";
    }
//users.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>User Registration System</title>
</head>
<body>
<div>
    <div>
        <a th:href="@{/}">Home</a>
    </div>
    <div>
        <h1>List of User</h1>
    </div>
    <table>
        <thead>
        <tr>
            <th>User ID</th>
            <th>User Email</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="user : ${users}">
            <td th:text="${user.id}"></td>
            <td th:text="${user.email}"></td>
        </tr>
        </tbody>
    </table>
</div>
</body>
</html>

啟動專案,前往http://localhost:8080/users,查看結果。

不用登入也沒有權限驗證,就能自由觀看這些機密資料,感覺有資料外洩的危機,應該要改成登入後才能觀看。

下個部分我們來開發登入功能

登入頁面

在AuthController.java添加進入登入頁面功能

//顯示登入頁面
    @GetMapping("/login")
    public String login(Model model) {
        return "login";
    }

設定登入頁面的內容

//login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>User Registration System</title>
</head>
<body>
<div>
  <div>
    <a th:href="@{/}">Home</a>
    <a th:href="@{/register}">Register</a>
  </div>

  <div>
    <form method="post" role="form" th:action="@{/login}">

      <div>
        <label>User Email</label>
        <input placeholder="Enter user email" type="text" id="email" name="email" />
      </div>

      <div>
        <label>User Password</label>
        <input placeholder="Enter user password" type="text" id="password" name="password" />
      </div>

      <button type="submit">Login</button>
      <span>Not registered? <a th:href="@{/register}">Register</a></span>
    </form>
  </div>

</div>
</body>
</html>

CSRF

跨站請求偽造(Cross-Site Request Forgery)是一種網路攻擊方式,如果在許多網站維持登入的狀態就有可能發生被CSRF的情況。

範例

如果你相信了,點擊以上連結,你就有可能在不知不覺中被CSRF攻擊了,打開的網站看似無害,實際上已經偷偷使用HTTP request method的GET進行一些危險操作。
這邊提供的範例是無害的,不過還是建議大家不要隨便點擊不明的連結。

為了避免有人成為受害者,專案管理員可以採取以下措施:

  • 使用CSRF Token驗證是使用者的操作
  • 檢查HTTP header fields中的Referer欄位,查看請求來源是否正確
  • 避免使用GET來發送重要的操作,POST至少需要在進入頁面後,按下按鈕送出才會被CSRF攻擊

Spring Security設定

Spring Security的設定就像一個鑰匙串,需要的功能就串上去,最後變成一大串。

在src/main/java/com/user_registration_system/user_registration_system/Config中,新增AppConfig.java。

@Configuration代表告知Spring,這些內容是用來管理專案的設定

//AppConfig.java

@Configuration
public class AppConfig {
    @Bean

用來管理Spring Security的權限設定

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

雖然之前說CSRF很恐怖,但我們不是銀行管理專案,不需要CSRF保護,將CSRF防護關閉。

http.csrf(csrf -> csrf.disable())

權限管理,符合/users/開頭的內容(authorizeRequests.requestMatchers("/users/")需要登入(.authenticated())才能存取

其餘的(.anyRequest())可以直接通過(.permitAll()),無需登入

這邊提供一些範例

⚠️代表要登入,✅代表無需登入

  • /users/⚠️
  • /users/a.html⚠️
  • /users/a/a.html⚠️
  • /a/a.html✅
  • /a.html✅
.authorizeHttpRequests(authorizeRequests -> authorizeRequests.requestMatchers("/users/**")
                        .authenticated()

                        .anyRequest()
                        .permitAll())

使用預設的Spring Security驗證方式

.httpBasic(Customizer.withDefaults())

登入表單的位置在/login

.formLogin(form -> form.loginPage("/login"))

登入的username欄位是email,這邊需要和login.html中欄位的id和name對應,否則找不到username

.usernameParameter("email")

登入的password欄位是password,需要對應login.html的欄位

.passwordParameter("password")

Spring Security會攔截POST /login的request,用來進行登入網站

.loginProcessingUrl("/login")

登入成功後,會轉移到/users

                        .defaultSuccessUrl("/users").permitAll());
        return http.build();
    }
}

我們還沒有導入自己的驗證系統,現在使用的是Spring Security預設的驗證系統。

啟動專案

  1. 嘗試進入http://localhost:8080/users
  2. 發現會立刻轉址到http://localhost:8080/login

我們要使用Spring Security提供的用戶名和密碼才能登入,用戶名是user,密碼需要在專案的控制台查看,類似

Using generated security password: 63df88fa-ecb9-4512-ae09-176864903b2f

每次產生的密碼都不相同,僅供測試使用。

  1. 在User Email填入user,User Password填看到的密碼(提供的範例中是63df88fa-ecb9-4512-ae09-176864903b2f),按下Login
  2. 就能看到全體用戶的Email列表。

我們也能自行設定用戶名和密碼,在application.properties添加

spring.security.user.name=user
spring.security.user.password=pw

現在我們每次都能使用固定的用戶名和密碼登入了。


上一篇
Day12 第五個Spring Boot專案:會員註冊登入系統(2)註冊
下一篇
Day14 第五個Spring Boot專案:會員註冊登入系統(4)登出和自訂驗證系統
系列文
我的SpringBoot絕學:7+2個專案,從新手變專家31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言