Written by : Nguyen Quoc Thai
Gmail: thaithedoublecheese1@gmail.com

1. Tổng quát

Hướng dẫn này sẽ giải thích cách thiết lập, cấu hình và tùy chỉnh Xác thực cơ bản với Spring. Chúng ta sẽ xây dựng dựa trên ví dụ Spring MVC đơn giản và bảo mật giao diện người dùng của ứng dụng MVC bằng cơ chế Authentication cơ bản do Spring Security cung cấp.

2. Cấu hình Spring Security

chúng ta sẽ cấu hình Spring security bằng java config

@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyBasicAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1").password(passwordEncoder().encode("user1Pass"))
          .authorities("ROLE_USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/securityNone").permitAll()
          .anyRequest().authenticated()
          .and()
          .httpBasic()
          .authenticationEntryPoint(authenticationEntryPoint);

        http.addFilterAfter(new CustomFilter(),
          BasicAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Ở đây chúng ta đang sử dụng phần tử httpBasic () để định nghĩa Xác thực Cơ bản bên trong phương thức config () của một lớp mở rộng WebSecurityConfigurerAdapter. Chúng tôi cũng có thể đạt được kết quả tương tự khi sử dụng XML:

<http pattern="/securityNone" security="none"/>
<http use-expressions="true">
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <http-basic />
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="user1" password="{noop}user1Pass" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

Điều liên quan ở đây là phần tử bên trong phần tử chính của cấu hình. Điều này đủ để kích hoạt Xác thực Cơ bản cho toàn bộ ứng dụng. Vì chúng ta không tập trung vào Trình quản lý xác thực trong hướng dẫn này, chúng ta sẽ sử dụng trình quản lý trong bộ nhớ với người dùng và mật khẩu được xác định ở dạng văn bản thuần túy.

web.xml của ứng dụng web kích hoạt Spring Security đã được thảo luận trong hướng dẫn Spring Logout.

3. Sử dụng ứng dụng bảo mật

Lệnh curl là công cụ cần thiết của chúng ta để sử dụng ứng dụng được bảo mật. Trước tiên, hãy thử yêu cầu /homepage.html mà không cung cấp bất kỳ thông tin xác thực bảo mật nào:

curl -i http://localhost:8080/spring-security-rest-basic-auth/api/foos/1

Chúng tôi nhận lại 401 Unauthorized và xác thực dự kiến:

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=E5A8D3C16B65A0A007CFAACAEEE6916B; Path=/spring-security-mvc-basic-auth/; HttpOnly
WWW-Authenticate: Basic realm="Spring Security Application"
Content-Type: text/html;charset=utf-8
Content-Length: 1061
Date: Wed, 29 May 2013 15:14:08 GMT

Thông thường, trình duyệt sẽ giải thích yêu cầu này và nhắc chúng ta về thông tin đăng nhập bằng một hộp thoại đơn giản, nhưng vì chúng ta đang sử dụng curl nên đây không phải là trường hợp.

Bây giờ, hãy yêu cầu cùng một tài nguyên, trang chủ, nhưng cung cấp thông tin đăng nhập để truy cập vào nó:

curl -i --user user1:user1Pass 
  http://localhost:8080/spring-security-rest-basic-auth/api/foos/1

Kết quả là, phản hồi từ máy chủ là 200 OK cùng với Cookie:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=301225C7AE7C74B0892887389996785D; Path=/spring-security-mvc-basic-auth/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en-US
Content-Length: 90
Date: Wed, 29 May 2013 15:19:38 GMT

Từ trình duyệt, chúng ta có thể sử dụng ứng dụng một cách bình thường; sự khác biệt duy nhất là trang đăng nhập không còn là yêu cầu khó vì tất cả các trình duyệt đều hỗ trợ Xác thực cơ bản và sử dụng hộp thoại để nhắc người dùng nhập thông tin đăng nhập.

4. Cấu hình bổ sung - Điểm đầu vào

Theo mặc định, BasicAuthenticationEntryPoint do Spring Security cung cấp trả về một trang đầy đủ cho phản hồi 401 Unauthorized trở lại máy khách. Biểu diễn lỗi HTML này hiển thị tốt trong trình duyệt. Ngược lại, nó không phù hợp với các tình huống khác, chẳng hạn như API REST, nơi biểu diễn json có thể được ưu tiên hơn. Không gian tên cũng đủ linh hoạt cho yêu cầu mới này. Để giải quyết vấn đề này, điểm nhập có thể được ghi đè:

<http-basic entry-point-ref="myBasicAuthenticationEntryPoint" />

Điểm vào mới được xác định là một bean tiêu chuẩn:

@Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(
      HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx) 
      throws IOException, ServletException {
        response.addHeader("WWW-Authenticate", "Basic realm="" + getRealmName() + """);
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = response.getWriter();
        writer.println("HTTP Status 401 - " + authEx.getMessage());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("Baeldung");
        super.afterPropertiesSet();
    }
}

Bằng cách ghi trực tiếp vào HTTP Response, giờ đây chúng ta có toàn quyền kiểm soát định dạng của phần thân phản hồi.

5.Thư viện Maven

Chúng tôi sẽ cần cả spring-security-web và spring-security-config có sẵn trong thời gian chạy

6.Kết Luận

Trong bài viết này, chúng ta đã bảo mật một ứng dụng MVC với Spring Security và Basic Authentication. Chúng ta đã thảo luận về cấu hình XML và chúng ta sử dụng ứng dụng với các lệnh curl đơn giản. Cuối cùng, chúng ta đã kiểm soát định dạng thông báo lỗi chính xác, chuyển từ trang lỗi HTML tiêu chuẩn sang định dạng văn bản hoặc JSON tùy chỉnh. Việc triển khai đầy đủ của bài viết này có thể được tìm thấy trong dự án GitHub. Đây là một dự án dựa trên Maven, vì vậy nó sẽ dễ dàng nhập và chạy như nó vốn có.