1. 概述
本教程將解釋如何設置、配置和自定義 基於 Spring 的基本身份驗證。我們將在此基礎之上,構建一個簡單的 Spring MVC 示例,並使用 Spring Security 提供的 Basic Auth 機制來保護 MVC 應用程序的用户界面。
2. Spring Security 配置
我們可以使用 Java 配置來配置 Spring Security:
@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter {
@Autowired private RestAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user1")
.password(passwordEncoder().encode("user1Pass"))
.authorities("ROLE_USER");
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(expressionInterceptUrlRegistry ->
expressionInterceptUrlRegistry.requestMatchers("/securityNone").permitAll()
.anyRequest().authenticated())
.httpBasic(httpSecurityHttpBasicConfigurer -> httpSecurityHttpBasicConfigurer.authenticationEntryPoint(authenticationEntryPoint));
http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}我們在這裏使用 httpBasic() 元素來定義 Basic Authentication 機制,位於 SecurityFilterChain Bean 中。
我們也可以使用 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>這裏重要的是配置中主
在 Spring Logout 教程中已經討論了 Web 應用程序的
我們使用 curl 命令來調用安全應用程序。 首先,我們嘗試請求 /homepage.html,但不提供任何安全憑據: 我們收到了預期的 401 未授權 以及 身份驗證挑戰: 正常情況下,瀏覽器會解析這個挑戰並要求我們提供憑據,通常會彈出一個簡單的對話框。但由於我們使用 curl,因此情況並非如此。 現在,讓我們請求相同的資源,即主頁,同時提供訪問它的憑據: 因此,服務器的響應是 200 OK,以及一個 Cookie。 從瀏覽器端,我們可以正常地消費該應用程序。唯一的區別在於,由於所有瀏覽器都支持 Basic Authentication,登錄頁不再是硬性要求,而是使用對話框提示用户輸入憑據。 默認情況下,Spring Security提供的BasicAuthenticationEntryPoint返回一個完整的頁面作為對401 Unauthorized響應的反饋給客户端。這種HTML形式的錯誤表示在瀏覽器中顯示良好。然而,它不適合其他場景,例如REST API,其中可能更喜歡JSON表示形式。 該命名空間足夠靈活,以滿足這一新要求。為了解決這個問題,可以覆蓋入口點: 新的入口點被定義為標準 Bean。 通過直接寫入 HTTP 響應,我們現在完全控制了響應體(response body)的格式。 Spring Security 的 Maven 依賴項在“Spring Security 與 Maven”文章中已經討論過。我們需要在運行時同時提供 spring-security-web 和 spring-security-config。 在本文中,我們使用 Spring Security 和 Basic Authentication 對 MVC 應用程序進行了安全保護。我們討論了 XML 配置,並使用簡單的 curl 命令消費了該應用程序。最後,我們控制了精確的錯誤消息格式,從標準 HTML 錯誤頁面轉移到自定義的文本或 JSON 格式。 當項目在本地運行時,樣本文檔可以在以下地址訪問: http://localhost:8080/spring-security-rest-basic-auth/api/foos/1。3. 調用安全應用程序
curl -i http://localhost:8080/spring-security-rest-basic-auth/api/foos/1HTTP/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 GMTcurl -i --user user1:user1Pass
http://localhost:8080/spring-security-rest-basic-auth/api/foos/1HTTP/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 GMT4. 進一步配置 – 入口點
<http-basic entry-point-ref="myBasicAuthenticationEntryPoint" />@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();
}
}5. Maven 依賴
6. 結論