拜读大佬博文
1. 核心组件
- SecurityContextHolder
SecurityContextHolder用于存储安全上下文的信息。
public interface SecurityContext extends Serializable {
//Authentication 封装了用户认证信息
Authentication getAuthentication();
void setAuthentication(Authentication authentication);
}
- Authentication:
public interface Authentication extends Principal, Serializable {
//权限信息列表,默认是GrantedAuthority的一些实现类,通常表现形式为代表用户权限信息的一系列字符串
Collection<? extends GrantedAuthority> getAuthorities();
//密码信息,用户输入的密码字符串,在认证过后通常会被移除,利于保障安全
Object getCredentials();
//细节性信息,记录了访问者的IP地址和sessionid的值。通常实现的接口为WebAuthenticationDetails
Object getDetails();
//最重要的用户身份信息,返回UserDetails接口的实现类
Object getPrincipal();
//用于告诉AbstractSecurityInterceptor 用户是否已经验证过
boolean isAuthenticated();
//设置用户认证状态
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}
- WebAuthenticationDetails
public class WebAuthenticationDetails implements Serializable {
private static final long serialVersionUID = 510L;
//用户的IP地址
private final String remoteAddress;
//用户的sessionId
private final String sessionId;
public WebAuthenticationDetails(HttpServletRequest request) {
this.remoteAddress = request.getRemoteAddr();
HttpSession session = request.getSession(false);
this.sessionId = session != null ? session.getId() : null;
}
private WebAuthenticationDetails(String remoteAddress, String sessionId) {
this.remoteAddress = remoteAddress;
this.sessionId = sessionId;
}
... //还有实现的hashCode方法和equals方法
}
- UserDetails
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
//用户账户是否过期
boolean isAccountNonExpired();
//用户账户是否被锁定
boolean isAccountNonLocked();
//用户密码是否过期
boolean isCredentialsNonExpired();
//用户是否被启用
boolean isEnabled();
}
- AuthenticationManager
本类是用户认证的核心接口,认证的发起方。
public interface AuthenticationManager {
//核心的认证方法,由实现类来具体完成验证的逻辑
Authentication authenticate(Authentication var1) throws AuthenticationException;
}
- ProviderManager
ProviderManager是AuthenticationManager的一个主要实现类,在里面维护了一个AuthenticationProvider的列表,存放多种认证方式的provider。默认情况下只要有一个认证方式能够通过那就是认证成功
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null;
Authentication result = null;
Authentication parentResult = null;
boolean debug = logger.isDebugEnabled();
//维护的认证Provider 列表
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
if (debug) {
logger.debug("Authentication attempt using "
+ provider.getClass().getName());
}
try {
//这里去获取验证结果
result = provider.authenticate(authentication);
if (result != null) {
copyDetails(authentication, result);
//只要有一个获得了认证成功,就不再接着认证其它的Provider
break;
}
}
catch (AccountStatusException e) {
prepareException(e, authentication);
throw e;
}
catch (InternalAuthenticationServiceException e) {
prepareException(e, authentication);
throw e;
}
catch (AuthenticationException e) {
lastException = e;
}
}
if (result == null && parent != null) {
try {
//TODO:这个地方有一个父类AuthenticationManager的实例,不知道在这里是什么作用。还有什么情况下parent引用不会为空,
result = parentResult = parent.authenticate(authentication);
}
catch (ProviderNotFoundException e) {
}
catch (AuthenticationException e) {
lastException = e;
}
}
if (result != null) {
if (eraseCredentialsAfterAuthentication
&& (result instanceof CredentialsContainer)) {
((CredentialsContainer) result).eraseCredentials();
}
if (parentResult == null) {
eventPublisher.publishAuthenticationSuccess(result);
}
return result;
}
if (lastException == null) {
lastException = new ProviderNotFoundException(messages.getMessage(
"ProviderManager.providerNotFound",
new Object[] { toTest.getName() },
"No AuthenticationProvider found for {0}"));
}
prepareException(lastException, authentication);
throw lastException;
}
- UserDetailsService
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
//这个方法的作用就是提供用户
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
大佬文章第一篇拜读完毕,效仿一下整理自己理解的UML图
第一篇读完有点感觉了
1. 用户信息的获取,UserDetailsService[loadUserByUsername(String username)]
2. 用户信息认证, AuthenticationProvider[authenticate(Authentication authentication)]
趁热打铁 大佬文章第二篇