Skip to content

5.3.3 Kích hoạt xác thực từ bên thứ ba

Bạn có thể đã từng thấy các liên kết hoặc nút trên trang web yêu thích của mình với dòng chữ như “Đăng nhập bằng Facebook”, “Đăng nhập bằng Twitter”, hoặc tương tự. Thay vì yêu cầu người dùng nhập thông tin xác thực trên một trang đăng nhập riêng của trang web, họ cung cấp một cách để đăng nhập thông qua một trang web khác như Facebook mà người dùng có thể đã đăng nhập sẵn.

Loại xác thực này dựa trên OAuth2 hoặc OpenID Connect (OIDC). Mặc dù OAuth2 là một đặc tả về ủy quyền (authorization), và chúng ta sẽ thảo luận thêm về cách sử dụng nó để bảo vệ các REST API trong chương 8, nó cũng có thể được dùng để thực hiện xác thực thông qua trang web của bên thứ ba. OpenID Connect là một đặc tả bảo mật khác được xây dựng trên OAuth2 để chuẩn hóa quá trình tương tác diễn ra trong xác thực từ bên thứ ba.

Để sử dụng loại xác thực này trong ứng dụng Spring của bạn, bạn cần thêm starter OAuth2 client vào phần build như sau:

xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Sau đó, ít nhất bạn cần cấu hình thông tin về một hoặc nhiều máy chủ OAuth2 hoặc OpenID Connect mà bạn muốn xác thực thông qua. Spring Security hỗ trợ sẵn việc đăng nhập với Facebook, Google, GitHub và Okta, nhưng bạn cũng có thể cấu hình các client khác bằng cách cung cấp thêm một số thuộc tính bổ sung.

Bộ thuộc tính cấu hình tổng quát mà bạn cần thiết lập để ứng dụng của bạn hoạt động như một client OAuth2/OpenID Connect như sau:

yaml
spring:
  security:
    oauth2:
      client:
        registration:
          <oauth2 or openid provider name>:
            clientId: <client id>
            clientSecret: <client secret>
            scope: <comma-separated list of requested scopes>

Ví dụ, giả sử rằng với Taco Cloud, bạn muốn người dùng có thể đăng nhập bằng Facebook. Cấu hình sau trong application.yml sẽ thiết lập OAuth2 client:

yaml
spring:
  security:
    oauth2:
      client:
      registration:
        facebook:
          clientId: <facebook client id>
          clientSecret: <facebook client secret>
          scope: email, public_profile

client-idclient-secret là các thông tin xác thực để nhận diện ứng dụng của bạn với Facebook. Bạn có thể lấy các thông tin này bằng cách tạo một ứng dụng mới tại: https://developers.facebook.com/. Thuộc tính scope chỉ định quyền truy cập mà ứng dụng sẽ được cấp. Trong trường hợp này, ứng dụng sẽ có quyền truy cập địa chỉ email và một số thông tin cơ bản từ hồ sơ công khai Facebook của người dùng.

Trong một ứng dụng đơn giản, chỉ cần như vậy là đủ. Khi người dùng cố gắng truy cập vào một trang yêu cầu xác thực, trình duyệt của họ sẽ được chuyển hướng đến Facebook. Nếu họ chưa đăng nhập vào Facebook, họ sẽ thấy trang đăng nhập của Facebook. Sau khi đăng nhập, họ sẽ được yêu cầu ủy quyền cho ứng dụng của bạn và cấp các quyền truy cập như đã yêu cầu. Cuối cùng, họ sẽ được chuyển hướng lại về ứng dụng của bạn và đã được xác thực.

Tuy nhiên, nếu bạn đã tùy chỉnh bảo mật bằng cách khai báo một bean SecurityFilterChain, thì bạn cần bật chức năng đăng nhập bằng OAuth2 cùng với các cấu hình bảo mật khác như sau:

java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  return http
    .authorizeRequests()
      .mvcMatchers("/design", "/orders").hasRole("USER")
      .anyRequest().permitAll()
    .and()
      .formLogin()
       .loginPage("/login")
    .and()
     .oauth2Login()

    ...

    .and()
    .build();
}

Bạn cũng có thể muốn cung cấp cả hai lựa chọn: đăng nhập truyền thống bằng tên người dùng - mật khẩu và đăng nhập từ bên thứ ba. Trong trường hợp đó, bạn có thể chỉ định trang đăng nhập trong cấu hình như sau:

java
.and()
  .oauth2Login()
    loginPage("/login")

Cấu hình này sẽ khiến ứng dụng luôn đưa người dùng đến trang đăng nhập do bạn cung cấp, nơi họ có thể chọn đăng nhập bằng tên người dùng và mật khẩu như thường lệ. Nhưng bạn cũng có thể đặt một liên kết trên trang đăng nhập đó để cho phép họ đăng nhập với Facebook. Một liên kết như vậy có thể trông như sau trong template HTML của trang đăng nhập:

html
<a th:href="/oauth2/authorization/facebook">Sign in with Facebook</a>

Released under the MIT License.