Giap Hiep

I'm Giap Hiep

I'm a web developer, a gymer. I enjoy share something i know that help people's work!
Giap Hiep

Multiple form login với spring boot

1. Giới thiệu

Trong các thực tế các ứng dụng web-app chúng ta đôi khi gặp phải trường hợp khách hàng muốn tạo 2 page login khác nhau dành cho user và admin vì vậy bài viết này tôi sẽ hướng dẫn các bạn cách cấu hình multiple form login trong spring boot.

2. Cấu hình

Chúng ta sẽ cần 2 class cấu hình cho form login của user và admin

class AdminSecurityConfig

@Configuration
@EnableWebSecurity
@Order(1)
public class AdminSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private PasswordEncoder passwordEncoder;

	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
		// account account1/admin1234
		auth.inMemoryAuthentication().passwordEncoder(passwordEncoder).withUser("account1")
				.password("$2a$04$PQtbtSAHZgBXLN.K/gZ3/eomQtZkB8R7x03KqZJxOTAbLRkxD9jgC").roles("ADMIN");

		// account acoount2/123456
		auth.inMemoryAuthentication().passwordEncoder(passwordEncoder).withUser("acoount2")
				.password("$2a$04$Q2Cq0k57zf2Vs/n3JXwzmerql9RzElr.J7aQd3/Sq0fw/BdDFPAj.").roles("USER");
		// auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("sena").password("123456").roles("USER");
	}

	protected void configure(HttpSecurity http) throws Exception {

		// Cấu hình security/form login cho url /admin/**
		// Cấu hình cho Login Form.
		http.antMatcher("/admin/**").authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").and().formLogin()//
				.loginProcessingUrl("/admin/j_spring_security_login")//
				.loginPage("/login1")//
				.defaultSuccessUrl("/admin")//
				.failureUrl("/login1?message=error")//
				.usernameParameter("username")//
				.passwordParameter("password")
				.and().exceptionHandling().accessDeniedPage("/403")
				.and().logout().logoutUrl("/admin/j_spring_security_logout").logoutSuccessUrl("/login1?message=logout");
	}

class UerSecurityConfig

@Configuration
@EnableWebSecurity
@Order(2)
public class UserSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private PasswordEncoder passwordEncoder;

	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
		
		// account account1/123456
		auth.inMemoryAuthentication().passwordEncoder(passwordEncoder).withUser("account1")
				.password("$2a$04$Q2Cq0k57zf2Vs/n3JXwzmerql9RzElr.J7aQd3/Sq0fw/BdDFPAj.").roles("ADMIN");

		// account account2/123456
		auth.inMemoryAuthentication().passwordEncoder(passwordEncoder).withUser("sena")
				.password("$2a$04$Q2Cq0k57zf2Vs/n3JXwzmerql9RzElr.J7aQd3/Sq0fw/BdDFPAj.").roles("USER");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// Cấu hình cho Login Form.
		http.authorizeRequests().antMatchers("/user/**").hasRole("USER").and()
				.formLogin()//
				.loginProcessingUrl("/j_spring_security_login")//
				.loginPage("/login2")//
				.defaultSuccessUrl("/user")//
				.failureUrl("/login2?message=error")//
				.usernameParameter("username").passwordParameter("password")
				.and().exceptionHandling().accessDeniedPage("/403")
				.and().logout().logoutUrl("/j_spring_security_logout").logoutSuccessUrl("/login2?message=logout");
	}

bây gờ chúng ta tạo các page để đăng nhập ở đây tôi dùng thymeleaf

User.html

<!DOCTYPE html>
<html>
<head>
<title>Spring Boot Security</title>
</head>
<body>
  <h2>User Page</h2>
  <h3>
    Welcome : <span th:utext="${#request.userPrincipal.name}"></span>
  </h3>
  <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>

admin.html

<!DOCTYPE html>
<html>
<head>
<title>Spring Boot Security</title>
</head>
<body>
  <h2>Admin Page</h2>
  <h3>
    Welcome : <span th:utext="${#request.userPrincipal.name}"></span>
  </h3>
  <br/>
  <form th:action="@{/admin/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>

Login2.html là user login page

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot Security</title>
</head>
<body>
  <h2>Form Login2</h2>
  <h4 th:text="${message}"></h4>
  <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>

login1.html là admin login page

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot Security</title>
</head>
<body>
  <h2>Form Login1</h2>
  <h4 th:text="${message}"></h4>
  <form name='login-form' th:action="@{/admin/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>

index.html

<!DOCTYPE html>
<html>
<head>
<title>Spring Boot Security</title>
</head>
<body>
	<h2>Demo Spring Boot - Multiple Form Login</h2>
	<a th:href="@{/admin}">admin page</a> <br />
	<a th:href="@{/user}">user page</a>

</body>
</html>
package multipleformlogin.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class BaseController {

    @RequestMapping("/login1")
    public String login1(@RequestParam(required = false) String message, final Model model) {
        logicLogin(message, model);
        return "login1";
    }

    @RequestMapping("/login2")
    public String login2(@RequestParam(required = false) String message, final Model model) {
        logicLogin(message, model);
        return "login2";
    }

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

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

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

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

    private void logicLogin(@RequestParam(required = false) String message, Model model) {
        if (message != null && !message.isEmpty()) {
            if (message.equals("logout")) {
                model.addAttribute("message", "Logout!");
            }
            if (message.equals("error")) {
                model.addAttribute("message", "Login Failed!");
            }
        }
    }

}

3 . Kết luận

Vậy là xong hẹn các bạn trong cái bài viết khác .