一、Authentication Provider概述
Authentication Provider是Spring Security中最核心的概念之一。簡單來說,它是處理用戶認證的組件,負責驗證用戶身份是否合法,並在驗證通過後返回身份信息給Spring Security。Authentication Provider對於Spring Security來說相當於是身份驗證的入口口。通過向Authentication Provider提供認證請求,我們可以得到認證結果,進而提供其他許可權控制服務。
在Spring Security中,Authentication Provider是一個介面,其實現類需要覆蓋authenticate(Authentication authentication)方法。當用戶請求認證時,Authentication Provider就會嘗試對用戶提供的信息進行認證評估,並返回Authentication對象。
二、Authentication Provider的使用方式
除了以前常用的XML方式進行配置,Spring Security 5開始提供了一種更為方便的Java Config方式進行Authentication Provider的配置。如果我們要使用這種方式,需要創建一個繼承了WebSecurityConfigurerAdapter的配置類,並在該類中重寫configure(AuthenticationManagerBuilder auth)方法,然後在該方法中註冊Authentication Provider。下面是一個簡單的示例代碼:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new CustomAuthenticationProvider());
}
private static class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return User.builder()
.username(username)
.password("{noop}password")
.roles("USER")
.build();
}
}
private static class CustomAuthenticationProvider implements AuthenticationProvider {
private final UserDetailsService userDetailsService;
public CustomAuthenticationProvider() {
this.userDetailsService = new CustomUserDetailsService();
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
UserDetails user = userDetailsService.loadUserByUsername(username);
if (password.equals(user.getPassword())) {
return new UsernamePasswordAuthenticationToken(username, password, user.getAuthorities());
} else {
throw new BadCredentialsException("Password is incorrect");
}
}
@Override
public boolean supports(Class authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
}
三、Authentication Provider的自定義
如果默認實現的Authentication Provider不能滿足我們的需求,我們也可以自己實現一個定製化的Authentication Provider。下面是一個自定義的Authentication Provider的示例代碼:
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
// 在此處根據用戶名和密碼進行自定義認證
if ("admin".equals(username) && "password".equals(password)) {
return new UsernamePasswordAuthenticationToken(username, password, new ArrayList());
} else {
throw new BadCredentialsException("Authentication failed");
}
}
@Override
public boolean supports(Class authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
四、Authentication Provider的擴展
在Spring Security中,我們還可以通過繼承AbstractUserDetailsAuthenticationProvider類來擴展Authentication Provider的功能。AbstractUserDetailsAuthenticationProvider提供了一些模板方法,可以讓我們方便地自定義擴展自己的Authentication Provider。下面是一個自定義擴展了AbstractUserDetailsAuthenticationProvider的示例代碼:
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
@Component
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
//在此處實現根據用戶名和密碼查找用戶信息的邏輯
}
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
//在此處實現額外的認證檢查邏輯
}
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/237108.html