1. 程式人生 > >使用Spring Security和Thymeleaf實現訪問控制

使用Spring Security和Thymeleaf實現訪問控制

  • 引入相關依賴
  <!--引入thymeleaf與Spring Security整合的依賴-->
   <dependency>
       <groupId>org.thymeleaf.extras</groupId>
       <artifactId>thymeleaf-extras-springsecurity4</artifactId>
       <version>3.0.2.RELEASE</version>
   </dependency>

   <!--引入Spring Security依賴-->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-security</artifactId>
   </dependency>

   <!--引入Thymeleaf依賴-->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-thymeleaf</artifactId>
   </dependency>
  • 建立自定義WebSecurityConfigurerAdapter並重寫configure方法
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {

    //攔截請求
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //設定哪些url允許被某種角色訪問
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/bronze").hasRole("英勇黃銅")
                .antMatchers("/silver").hasRole("不屈白銀")
                .antMatchers("/gold").hasRole("榮耀黃金")
                .antMatchers("/platinum").hasRole("華貴鉑金")
                .antMatchers("/diamond").hasRole("璀璨鑽石")
                .antMatchers("/master").hasRole("超凡大師")
                .antMatchers("/challenger").hasRole("最強王者");

        //啟用登入功能,可以使用預設的登入頁,這裡使用自定義的login.html頁面
        http.formLogin().loginPage("/login");

        //啟用登出功能,(需要提供一個action為/logout的form)並設定登出後訪問的url,這裡登出後跳轉到首頁
        http.logout().logoutSuccessUrl("/");

        //啟用rememberMe功能,將使用者資訊儲存在cookie中
        http.rememberMe();
    }

    //授權認證
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //inMemoryAuthentication表示使用基於記憶體的驗證,還可以使用基於資料庫的驗證等,使用BCrypt編碼對密碼進行加密
        //,否則報錯java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("bronze")
                .password(new BCryptPasswordEncoder().encode("0110")).roles("英勇黃銅")
                .and().withUser("silver").password(new BCryptPasswordEncoder()
                .encode("0110")).roles("不屈白銀").and().withUser("gold")
                .password(new BCryptPasswordEncoder().encode("0110")).roles("榮耀黃金")
                .and().withUser("platinum").password(new BCryptPasswordEncoder()
                .encode("0110")).roles("華貴鉑金").and().withUser("diamond")
                .password(new BCryptPasswordEncoder().encode("0110")).roles("璀璨鑽石")
                .and().withUser("master").password(new BCryptPasswordEncoder()
                .encode("0110")).roles("超凡大師").and().withUser("challenger")
                .password(new BCryptPasswordEncoder().encode("0110")).roles("最強王者");
    }
}
  • 主頁顯示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>

<div align="center" style="margin-top: 15px" sec:authorize="!isAuthenticated()">
    <h4 style="color: blue;">歡迎您,親愛的召喚師!<a th:href="@{/login}"> 請登入</a></h4>
</div>

<div align="center" style="margin-top: 15px" sec:authorize="isAuthenticated()">
    <h4 style="color: blue;">召喚師 <span sec:authentication="name"></span>
        ! 您的段位為:<span sec:authentication="principal.authorities"></span>
    </h4>
    <form th:action="@{/logout}" method="post">
        <input type="submit" th:value="登出登入">
    </form>
</div>

<div align="center" style="margin-top: 100px" sec:authorize="hasRole('英勇青銅')">
    <a th:href="@{/bronze}">點選領取英勇青銅段位獎勵</a>
</div>
<div align="center" style="margin-top: 100px" sec:authorize="hasRole('不屈白銀')">
    <a th:href="@{/silver}">點選領取不屈白銀段位獎勵</a>
</div>
<div align="center" style="margin-top: 100px" sec:authorize="hasRole('榮耀黃金')">
    <a th:href="@{/gold}">點選領取榮耀黃金段位獎勵</a>
</div>
<div align="center" style="margin-top: 100px" sec:authorize="hasRole('華貴鉑金')">
    <a th:href="@{/platinum}">點選領取華貴鉑金段位獎勵</a>
</div>
<div align="center" style="margin-top: 100px" sec:authorize="hasRole('璀璨鑽石')">
    <a th:href="@{/diamond}">點選領取璀璨鑽石段位獎勵</a>
</div>
<div align="center" style="margin-top: 100px" sec:authorize="hasRole('超凡大師')">
    <a th:href="@{/master}">點選領取超凡大師段位獎勵</a>
</div>
<div align="center" style="margin-top: 100px" sec:authorize="hasRole('最強王者')">
    <a th:href="@{/challenger}">點選領取最強王者段位獎勵</a>
</div>

</body>
</html>
  • 點選領取獎勵頁面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>英勇黃銅</title>
</head>
<body>

<div align="center" style="margin-top: 20px">
    <a th:href="@{/}">返回首頁</a>
</div>

<div align="center" style="margin-top: 100px">
    <h3>您在本賽季段位為:<span style="color: aqua;font-style: italic">英勇黃銅</span></h3>
    <h4>獲得面板獎勵:<span style="color: peru">鏽跡斑斑 布里茨</span></h4>
</div>

</body>
</html>
  • 自定義登入頁面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登入</title>
</head>
<body>

<div align="center" style="margin-top: 60px">
    <form th:action="@{/login}" method="post">
        <p>
            <label>Username</label>
            <input type="text" th:name="username">
        </p>
        <p>
            <label>Password</label>
            <input type="password" th:name="password">
        </p>
        <p>
            <label>Remember Me</label>
            <input type="checkbox" th:name="remember-me">
        </p>
        <div align="center">
            <input type="submit" th:value="登入">
        </div>
    </form>
</div>

</body>
</html>
測試結果:
  • 首頁
    首頁

  • 登入頁,點選Remember Me下次訪問不需要重新登入
    登入頁

  • 登入成功
    登入成功

  • 獎勵頁面
    獎勵頁面