首页 > 数据库 > 数据库开发技术 > SpringSecurity 整体认证流程
HttpSecurityConfiguration创建了HttpSecurity ——> HttpSecurity会构建DefaultSecurityFilterChain
WebSecurityConfiguration会将DefaultSecurityFilterChain注入到securityFilterChains属性中。并将DefaultSecurityFilterChain添加到WebSecurity中,最终由 WebSecurity 构建出 FilterChainProxy 来执行SpringSecurity 的过滤逻辑。
DelegatingFilterProxy是springWeb中的类,有一个delegate属性其值为FilterChainProxy对象。「DelegatingFilterProxy是真正会注册到Tomcat容器中的Filter」
Authentication 代表请求认证的token,或通过AuthenticationManager.authenticate(Authentication)认证过的主体对象
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
// 登录凭证
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}
AuthenticationProvider:做认证和授权的。策略模式非常适合一个问题有多种解决方案的场景。对扩展开放解耦。比如一个用户有多种登录方式,用户名密码、手机号验证码、微信登录等等。
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
boolean supports(Class<?> authentication);
}
ProviderManager:实现了AuthenticationManager,持有所有认证策略(AuthenticationProvider)。并且还有一个父类属性ProviderManager。
认证流程:先使用自己持有的AuthenticationProvider进行认证,如果没有认证成功再使用父类的ProviderManager进行认证。
ProviderManager的核心方法就是authenticate方法。
public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {
private List<AuthenticationProvider> providers = Collections.emptyList();
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private AuthenticationManager parent;
// 是否擦除认证信息,认证成功后擦除凭证(密码)
private boolean eraseCredentialsAfterAuthentication = true;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 使用自身的AuthenticationProvider进行认证
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
result = provider.authenticate(authentication);
}
// 未认证,使用父认证AuthenticationProvider进行认证
if (result == null && this.parent != null) {
parentResult = this.parent.authenticate(authentication);
result = parentResult;
}
if (result != null) {
// 认证成功后,擦除认证信息(密码)
if (this.eraseCredentialsAfterAuthentication && (result instanceof CredentialsContainer)) {
if (parentResult == null) {
this.eventPublisher.publishAuthenticationSuccess(result);
}
return result;
}
// parent是空,并且也没有认证处理器处理就抛出异常
if (lastException == null) {
lastException = new ProviderNotFoundException(this.messages.getMessage("ProviderManager.providerNotFound",
new Object[] { toTest.getName() }, "No AuthenticationProvider found for {0}"));
}
// 处理异常
if (parentException == null) {
prepareException(lastException, authentication);
}
throw lastException;
}
}
AuthenticationManager:处理认证Authentication请求。重要的实现类为AuthenticationProvider。
// Processes an Authentication request.
public interface AuthenticationManager {
/**
* 尝试通过 Authentication 对象做认证。
* 返回已经认证的(填充了认证信息和授权信息)的Authentication
*/
Authentication authenticate(Authentication authentication) throws AuthenticationException;
}
AuthenticationManagerBuilder:是SecurityBuilder的子类用于构建AuthenticationManager。performBuild方法构建的就是一个ProviderManager对象,构造器中传入了authenticationProviders和parentAuthenticationManager来
public class AuthenticationManagerBuilder
extends AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>
implements ProviderManagerBuilder<AuthenticationManagerBuilder>{
@Override
protected ProviderManager performBuild() throws Exception {
// 直接new来创建ProviderManager,传入了authenticationProviders和父parentAuthenticationManager
ProviderManager providerManager = new ProviderManager(this.authenticationProviders, this.parentAuthenticationManager);
if (this.eraseCredentials != null) {
providerManager.setEraseCredentialsAfterAuthentication(this.eraseCredentials);
}
if (this.eventPublisher != null) {
providerManager.setAuthenticationEventPublisher(this.eventPublisher);
}
// 安全对象的后处理,对安全对象的扩展
providerManager = postProcess(providerManager);
return providerManager;
}
}
欢迎加入 DevXTalk 的技术交流群,在这里你可以和大佬们一起交流分享技术,行业经验,提升自我。结识新的业内朋友,扩大自己的圈子,当你想换工作的时候也许就能拿到不错的 offer 。总之期待你的加入...
「看完本文有收获?转发给更多的朋友吧」
「DevXTalk 不止于技术」
原文作者:DevXTalk;如有侵权,请联系管理员删除。