• Tìm việc IT
  • Tạo CV Online
  • CÔNG TY TUYỂN DỤNG IT
  • Lập Trình
    • AI – Machine Learning
    • Frontend
    • Backend
    • Fullstack
    • Mobile
    • Product
    • Devops
    • Java
    • PHP
    • Python
    • Xu hướng công nghệ
    • Tổng quan ngành IT
      • Báo cáo thị trường IT
      • Con đường sự nghiệp IT
      • Chuyên gia nói
      • Sự kiện IT
    • Developer Resources
      • Sách lập trình
      • Tài liệu lập trình
      • Source Code
  • KỸ NĂNG TÌM VIỆC
    • Kinh nghiệm phỏng vấn
    • Chuẩn hóa CV IT
    • Đàm phán lương thưởng
    • Cẩm nang tuyển dụng
      • Tìm kiếm nhân tài
      • Nghệ thuật quản trị
  • Trắc nghiệm tính cách
Search
  • 028.6273.3496
  • Post a job
  • Contact us
Sign in
Welcome! Log into your account
Forgot your password? Get help
Password recovery
Recover your password
A password will be e-mailed to you.
TopDev
  • Tìm việc IT
  • Tạo CV Online
  • CÔNG TY TUYỂN DỤNG IT
  • Lập Trình
    • AI – Machine Learning
    • Frontend
    • Backend
    • Fullstack
    • Mobile
    • Product
    • Devops
    • Java
    • PHP
    • Python
    • Xu hướng công nghệ
    • Tổng quan ngành IT
      • Báo cáo thị trường IT
      • Con đường sự nghiệp IT
      • Chuyên gia nói
      • Sự kiện IT
    • Developer Resources
      • Sách lập trình
      • Tài liệu lập trình
      • Source Code
  • KỸ NĂNG TÌM VIỆC
    • Kinh nghiệm phỏng vấn
    • Chuẩn hóa CV IT
    • Đàm phán lương thưởng
    • Cẩm nang tuyển dụng
      • Tìm kiếm nhân tài
      • Nghệ thuật quản trị
  • Trắc nghiệm tính cách
Home Công nghệ Multiple login page với Spring Security
  • Công nghệ
  • Lập Trình

Multiple login page với Spring Security

1284
Facebook
Linkedin
Telegram

    Mục lục nội dung

    1. Ứng dụng ví dụ
      1. Cấu hình Spring Security

    Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

    Trong các dự án thực tế, các bạn sẽ gặp những trường hợp mà ứng dụng cần thiết phải sử dụng 2 cách login khác nhau tuỳ theo role của user, ví dụ như có những ứng dụng sẽ cần user bình thường login sử dụng token hoặc QR code, còn admin thì login sử dụng username, password. Để hiện thực multiple login page sử dụng Spring Security như thế nào? Mình sẽ hướng dẫn các bạn trong bài viết này các bạn nhé!

      Bảo mật ứng dụng Java web bởi Spring Security
      Cách sử dụng properties trong tập tin cấu hình của Spring

    Ứng dụng ví dụ

    Đầu tiên, mình sẽ tạo mới một Spring Boot project với Spring Security Starter, Spring Web Starter, Thymeleaf Starter:

    Multiple login page với Spring Security

    và WebJars với Bootstrap dependency để làm ví dụ như sau:

    <dependency>
    <groupId>org.webjars</groupId>
    <artifactId>webjars-locator-core</artifactId>
    </dependency>
    <dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>5.0.2</version>
    </dependency>

    Kết quả:

    Multiple login page với Spring Security

    Để thể hiện nhu cầu mà chúng ta đang muốn giải quyết, mình sẽ tạo một controller để expose ra 2 trang, một chỉ cho user có role là USER access và một chỉ cho user có role ADMIN access. Cụ thể như sau:

    package com.huongdanjava.springsecurity;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class ApplicationController {
    
    @GetMapping("/user/view")
    public String userView() {
    return "user";
    }
    
    @GetMapping("/admin/view")
    public String adminView() {
    return "admin";
    }
    
    }

    Thymeleaf template cho các trang này như sau:

    admin.html:

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Spring Security Example</title>
    <link href="/webjars/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container">
    <h2 class="form-signin-heading">Hello Admin</h2>
    </div>
    </body>
    </html>

    user.html:

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Spring Security Example</title>
    <link href="/webjars/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container">
    <h2 class="form-signin-heading">Hello User</h2>
    </div>
    </body>
    </html>

    Lúc này, nếu các bạn chạy ứng dụng lên và request tới 2 trang này, trang login mặc định của Spring Security sẽ luôn được hiển thị.

    Mình sẽ sử dụng trang login mặc định của Spring Security cho user “admin” với username và password, còn user bình thường “user” thì mình sẽ sử dụng một custom login page cũng với username và password, tương tự như mình đã làm trong bài viết Custom login page sử dụng Bootstrap và Thymeleaf trong Spring Security.

    Code trang login-user.html cho user bình thường đăng nhập như sau:

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Spring Security Example</title>
    <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container">
    <h2 class="form-signin-heading">Welcome to Huong Dan Java, please login</h2>
    <div th:if="${param.error}" class="alert alert-danger"> 
    Invalid username and password.
    </div>
    <div th:if="${param.logout}" class="alert alert-success"> 
    You have been logged out.
    </div>
    <form class="form-signin" method="POST" th:action="@{/login}">
    <p>
    <label for="username" class="sr-only">Username</label> 
    <input type="text" id="username" name="username" class="form-control"
    placeholder="Username" required autofocus>
    </p>
    <p>
    <label for="password" class="sr-only">Password</label> 
    <input type="password" id="password" name="password" class="form-control"
    placeholder="Password" required>
    </p>
    <button class="btn btn-lg btn-primary btn-block" type="submit">Login</button>
    </form>
    </div>
    </body>
    </html>

    Expose trang login với token này trong class ApplicationController như sau::

    @GetMapping("/user-login")
    public String userLoginView() {
    return "login-user";
    }

    Bây giờ mình sẽ cấu hình cho Spring Security cho request tới 2 trang này.

    Cấu hình Spring Security

    Đầu tiên, mình sẽ cấu hình thông tin về user sẽ đăng nhập vào ứng dụng ví dụ.

    Như mình nói ở trên, chúng ta sẽ có 2 user là “user” và “admin” với role tương ứng là “USER” và “ADMIN”. Cả hai user này sẽ sử dụng chung một source cho phần authentication, điều này có nghĩa là chúng được lưu trữ ở một nơi giống nhau, trong bài viết này chúng ta sẽ sử dụng source là in memory.

    Mình sẽ tạo bean cho đối tượng UserDetailsService chứa thông tin của 2 user này như sau:

    package com.huongdanjava.springsecurity;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.provisioning.InMemoryUserDetailsManager;
    
    @SpringBootApplication
    public class SpringSecurityMultipleLoginApplication {
    
    public static void main(String[] args) {
    SpringApplication.run(SpringSecurityMultipleLoginApplication.class, args);
    }
    
    @Bean
    public UserDetailsService userDetailsService() throws Exception {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User
    .withUsername("user")
    .password(encoder().encode("user"))
    .roles("USER")
    .build());
    
    manager.createUser(User
    .withUsername("admin")
    .password(encoder().encode("admin"))
    .roles("ADMIN")
    .build());
    
    return manager;
    }
    
    @Bean
    public static PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
    }
    
    }

    Tiếp theo, chúng ta sẽ cấu hình Spring Security.

    Ở đây, là vì chúng ta cần handle request cho user có role “USER” thì hiển thị trang custom login còn user có role “ADMIN” sẽ hiển thị trang login mặc định của Spring Security nên mình sẽ định nghĩa multiple class extends abstract class WebSecurityConfigurerAdapter với order như sau:

    package com.huongdanjava.springsecurity;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.security.config.Customizer;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    
    @EnableWebSecurity
    public class SpringSecurityConfiguration {
    
    @Configuration
    @Order(1)
    public class UserSpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    // @formatter:off
    http.antMatcher("/user/**")
    .authorizeRequests()
    .anyRequest().hasRole("USER")
    .and()
    .formLogin()
    .loginPage("/user-login")
    .failureUrl("/user-login?error")
    .permitAll();
    // @formatter:on
    }
    }
    
    @Configuration
    public class AdminSpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    // @formatter:off
    http
    .authorizeRequests()
    .antMatchers("/user-login/**").permitAll()
    .anyRequest().hasRole("ADMIN")
    .and()
    .formLogin(Customizer.withDefaults());
    // @formatter:on
    }
    
    @Override
    public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/webjars/**");
    }
    }
    
    }

    Ở đây, mình đang khai báo để handle cho request của user bình thường sử dụng class UserSpringSecurityConfiguration còn admin user thì những request còn lại. Mình chỉ khai báo @Order annotation cho class UserSpringSecurityConfiguration để nó được gọi đầu tiên để handle bất kỳ request nào, nếu không thoả điều kiện antMatcher() để nó handle request đó thì class AdminSpringSecurityConfiguration sẽ handle.

    Như các bạn thấy, đối với những request bắt đầu với “/user”, nếu user không

    có role “USER”, mình cấu hình cho ứng dụng ví dụ của chúng ta redirect tới trang “/user-login” để user có thể login, lúc này class AdminSpringSecurityConfiguration sẽ handle request “/user-login” này. Trong class AdminSpringSecurityConfiguration, mình đã cấu hình đối với request bắt đầu bằng “/user-login”, chúng ta sẽ permitAll(). Lúc này trang “/user-login” sẽ được hiển thị. Nếu đăng nhập thành công và user có role “USER” thì chúng ta có thể đăng nhập request bắt đầu với “/user” này.

    Chạy ứng dụng và request tới http://localhost:8080/user/view, các bạn sẽ thấy trang custom login hiển thị như sau:

    Multiple login page với Spring Security

    Đăng nhập với user “user” và password là “user”, các bạn sẽ thấy kết quả như sau:

    Multiple login page với Spring Security

    Còn nếu các bạn request tới http://localhost:8080/admin/view, các bạn sẽ thấy trang login mặc định của Spring Security hiển thị. Đăng nhập với user “admin” và password “admin”, các bạn sẽ thấy kết quả như sau:

    Multiple login page với Spring Security

    Trong class AdminSpringSecurityConfiguration, mình đã cấu hình cho những request còn lại, ngoại trừ request “/user/**”, user phải có role là “ADMIN”.

    Các bạn hãy nhớ là, để cấu hình cho những specific riêng biệt thì chúng ta sẽ sử dụng phương thức antMatcher() của đối tượng HttpSecurity với value là request URL mà chúng ta cần. Cho những request còn lại thì các bạn đừng khai báo annotation @Order với class cấu hình, để nó luôn là order cao nhất.

    Bài viết gốc được đăng tải tại huongdanjava.com

    Có thể bạn quan tâm:

    • Custom login page sử dụng Bootstrap và Thymeleaf trong Spring Security
    • Sử dụng Spring Security trong Spring Boot
    • Custom authentication filter đăng nhập không cần password trong Spring Security

    Xem thêm Việc làm IT hấp dẫn trên TopDev

    • TAGS
    • multiple login page
    • spring security
    Facebook
    Linkedin
    Telegram
      TopDev
      Ban Biên Tập Blog TopDev. Nice to meet you

      RELATED ARTICLESMORE FROM AUTHOR

      authentication

      Authentication trong Spring Security

      Custom authentication filter đăng nhập không cần password trong Spring Security

      Custom authentication filter đăng nhập không cần password trong Spring Security

      Custom login page sử dụng Bootstrap và Thymeleaf trong Spring Security

      Custom login page sử dụng Bootstrap và Thymeleaf trong Spring Security

      Sử dụng Spring Security trong Spring Boot

      Sử dụng Spring Security trong Spring Boot

      Bảo mật ứng dụng Java web bởi Spring Security

      Bảo mật ứng dụng Java web bởi Spring Security

      ĐỪNG BỎ LỠ

      • Type Query trong GraphQL với Spring Boot
      • Giới thiệu về Spring Integration
      • Giới thiệu về GraphQL. Cách giải quyết những hạn chế của RESTful API
      • Publish message vào Google Pub/Sub topic sử dụng Spring Cloud GCP
      • Cấu hình Spring Data JPA với @EnableJpaRepositories annotation

      VIỆC LÀM IT LƯƠNG CAO

      • Việc làm Php
      • Việc làm Javascript
      • Việc làm Java
      • Việc làm Frontend
      • Việc làm Backend
      • Việc làm .Net
      • Việc làm Python
      • Việc làm Golang
      • Việc làm iOS
      • Việc làm Android
      • Việc làm Flutter
      • Việc làm Tester
      • Việc làm Nodejs
      ABOUT US
      TopDev is a recruitment network and ecosystem in Mobile & IT fields. We are top leading recruitment network in Mobile & IT fields, in Vietnam, offering Tech talent solution which meets your needs. Our networks cover 95% of Tech communities in Vietnam and our clients come from both Vietnam and South East Asia.
      Hotline: 028 6273 3496

      app_store google_play
      Contact us: contact@topdev.vn
      FOLLOW US