Code ví dụ Spring Boot Security Hello + Tạo Form Login

Code ví dụ Spring Boot Security Hello + Tạo Form Login

(Xem lại: Code ví dụ Spring MVC Security Hello World – XML Config)

Các công nghệ sử dụng:

Tạo Spring Boot Project:

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Ở đây mình dùng template engine là Thymleaf để hiển thị view .html

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Cấu trúc Project

Code ví dụ Spring Boot Security Hello + Tạo Form Login

File start ứng dụng:

package stackjava.com.sbsecurityhello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootSecurityHelloApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootSecurityHelloApplication.class, args);
  }
}

File cấu hình spring security:

package stackjava.com.sbsecurityhello.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        return bCryptPasswordEncoder;
    }
  
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).
      withUser("kai").password("$2a$04$Q2Cq0k57zf2Vs/n3JXwzmerql9RzElr.J7aQd3/Sq0fw/BdDFPAj.").roles("ADMIN");
    auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).
      withUser("sena").password("$2a$04$Q2Cq0k57zf2Vs/n3JXwzmerql9RzElr.J7aQd3/Sq0fw/BdDFPAj.").roles("USER");
    
//		auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("sena").password("123456").roles("USER");
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {

    // Chỉ cho phép user có quyền ADMIN truy cập đường dẫn /admin/**
    http.authorizeRequests().antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')");

    // Chỉ cho phép user có quyền ADMIN hoặc USER truy cập đường dẫn /user/**
    http.authorizeRequests().antMatchers("/user/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')");

    // Khi người dùng đã login, với vai trò USER, Nhưng truy cập vào trang yêu cầu vai trò ADMIN, sẽ chuyển hướng tới trang /403
    http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/403");

    // Cấu hình cho Login Form.
    http.authorizeRequests().and().formLogin()//
        .loginProcessingUrl("/j_spring_security_login")//
        .loginPage("/login")//
        .defaultSuccessUrl("/user")//
        .failureUrl("/login?message=error")//
        .usernameParameter("username")//
        .passwordParameter("password")
        // Cấu hình cho Logout Page.
        .and().logout().logoutUrl("/j_spring_security_logout").logoutSuccessUrl("/login?message=logout");

  }
}

Ở đây mình config chỉ cho user có role là ADMIN truy cập các url /admin/**, các user có role ADMIN hoặc USER được truy cập url /user/**

Nhìn chung các config bằng Java khá giống với việc config bằng xml.

File Controller:

package stackjava.com.sbsecurityhello.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class BaseController {

  @RequestMapping(value={"/","/login"})
  public String login() {
    return "login";
  }

  @RequestMapping("/user")
  public String user() {
    return "user";
  }

  @RequestMapping("/admin")
  public String admin() {
    return "admin";
  }

  @RequestMapping("/403")
  public String accessDenied() {
    return "403";
  }
}

Các file views:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot Security Hello</title>
</head>
<body>
  <h2>Spring Boot Security Hello</h2>
  <form name='login-form' th:action="@{/j_spring_security_login}" method='POST'>
    <table>
      <tr>
        <td>Username:</td>
        <td><input type='text' name='username' value=''></td>
      </tr>
      <tr>
        <td>Password:</td>
        <td><input type='password' name='password' /></td>
      </tr>
      <tr>
        <td><input name="submit" type="submit" value="submit" /></td>
      </tr>
    </table>
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
  </form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Spring Boot Security Hello</title>
</head>
<body>
  <h2>User Page</h2>
  <h3>
    Welcome : <span th:utext="${#request.userPrincipal.name}"></span>
  </h3>

  <a th:href="@{/admin}">Admin Page</a>

  <br/><br/>
  <form th:action="@{/j_spring_security_logout}" method="post">
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
    <input type="submit" value="Logout" />
  </form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Spring Boot Security Hello</title>
</head>
<body>
  <h2>Admin Page</h2>
  <h3>
    Hello : <span th:utext="${#request.userPrincipal.name}"></span>
  </h3>
  
  
  <a th:href="@{/user}">User Page</a>

  <br/><br/>
  <form th:action="@{/j_spring_security_logout}" method="post">
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
    <input type="submit" value="Logout" />
  </form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Spring Boot Security Hello</title>
</head>
<body>
  <h2>Access Denied Page - 403</h2>
  
  <h3>
    Hi : <span th:utext="${#request.userPrincipal.name} + ' - you do not have permission to access this page'"></span>
  </h3>

  <a th:href="@{/user}">User Page</a>

  <br/><br/>
  <form th:action="@{/j_spring_security_logout}" method="post">
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
    <input type="submit" value="Logout" />
  </form>
</body>
</html>

Demo:

Đăng nhập với tài khoản kai/123456 – (role = ROLE_ADMIN)

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Đăng nhập với tài khoản sena/123456 (role = ROLE_USER)

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Tài khoản sena/123456 không có role ROLE_ADMIN nên sẽ bị từ chối truy cập trang /admin

Code ví dụ Spring Boot Security Hello + Tạo Form Login

Code ví dụ Spring Boot Security Hello + Tạo Form Login stackjava.com

Okay, Done!
Download code ví dụ trên tại đây.

 

 

References:

https://docs.spring.io/spring-security/site/docs/5.0.0.RELEASE/reference/htmlsingle

stackjava.com