1. 概述
在本教程中,我們將學習如何設置 Spring Security 中的身份驗證提供者,這與僅使用簡單的 UserDetailsService 方案相比,提供了更大的靈活性。
2. 身份驗證提供者
Spring Security 提供多種身份驗證選項。這些選項遵循一個簡單的約定:一個 身份驗證提供者 處理一個 身份驗證 請求,並返回一個包含完整憑據的完全身份驗證對象。
標準且最常見的實現是 DaoAuthenticationProvider,它從一個簡單的、只讀的用户 DAO,即 用户詳情服務 中檢索用户詳細信息。該用户詳情服務 僅訪問用户名,以便檢索完整的用户實體,對於大多數場景來説已經足夠。
更復雜的場景仍然需要訪問完整的 身份驗證 請求,以便執行身份驗證過程。例如,當與某些第三方服務進行驗證(例如 Crowd 時,身份驗證請求中的用户名和密碼都需要。
對於這些更高級的場景,我們需要 定義一個自定義身份驗證提供者:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
final String name = authentication.getName();
final String password = authentication.getCredentials().toString();
if (!"admin".equals(name) || !"system".equals(password)) {
return null;
}
return authenticateAgainstThirdPartyAndGetAuthentication(name, password);
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}這裏有一個通用的方法,它返回一個 Authentication 對象。 它的實現可以根據我們想要如何進行身份驗證而變化。 例如,我們可以編寫一個固定憑據方法的示例:
private static UsernamePasswordAuthenticationToken authenticateAgainstThirdPartyAndGetAuthentication(String name, String password) {
final List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
final UserDetails principal = new User(name, password, grantedAuths);
return new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
}值得注意的是,我們還為我們的 UserDetails 對象添加了權限。在實際應用中,根據您的需求實現上述方法是必要的,因為短文可能無法覆蓋所有情況。
3. 註冊身份驗證提供者
現在我們已經定義了身份驗證提供者,需要使用可用的命名空間支持,在 XML 安全配置中指定它:
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()"/>
<http-basic/>
</http>
<authentication-manager>
<authentication-provider
ref="customAuthenticationProvider" />
</authentication-manager>4. Java 配置
接下來,我們將查看相應的 Java 配置:
@Configuration
@EnableWebSecurity
@ComponentScan("com.baeldung.security")
public class SecurityConfig {
@Autowired
private CustomAuthenticationProvider authProvider;
@Bean
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder =
http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.authenticationProvider(authProvider);
return authenticationManagerBuilder.build();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(request -> request.anyRequest()
.authenticated())
.httpBasic(Customizer.withDefaults())
.build();
}
}在這裏,我們配置了所有請求所需的身份驗證,並配置了 HTTP 基本身份驗證。
5. 執行身份驗證
從客户端請求身份驗證與或不與此自定義身份驗證提供程序在後端使用基本相同。
我們將使用一個簡單的 curl 命令來發送一個經過身份驗證的請求:
curl --header "Accept:application/json" -i --user user1:user1Pass
http://localhost:8080/spring-security-custom/api/foo/1為了這個示例,我們使用基本身份驗證來保護 REST API。
並且我們從服務器獲得了預期的 200 OK 響應:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=B8F0EFA81B78DE968088EBB9AFD85A60; Path=/spring-security-custom/; HttpOnly
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 02 Jun 2013 17:50:40 GMT6. 結論
在本文中,我們探討了一個自定義身份驗證提供程序的示例,用於 Spring Security。