SpringSecurity源码分析(RemeberMe)

RememberMeServices

RememberMeServices
记住我的服务的接口
可以重写实现自己的记住我

public interface RememberMeServices {
//建议 org. springframework. security. authentication. RememberMeAuthenticationToken 在大多数情况下使用它,因为它具有相应的身份验证提供程序。
	Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
	void loginFail(HttpServletRequest request, HttpServletResponse response);
	void loginSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication successfulAuthentication);
}

AbstractRememberMeServices
记住我基类

public abstract class AbstractRememberMeServices
		implements RememberMeServices, InitializingBean, LogoutHandler, MessageSourceAware {
}
  1. 从请求内获取cookie
  2. 判断cookie长度是否为0,为0删除cookie
  3. cookie解码
  4. 执行autoLoginCookie,返回用户详细信息
  5. 检查cookie判断是否被禁用
  6. 创建从 autoLogin 方法返回的最终 Authentication 对象。

在这里插入图片描述
在请求中找到 Spring Security 记住我 cookie 并返回其值。
在这里插入图片描述
在这里插入图片描述
当MaxAge为0时候表示删除cookie
在这里插入图片描述
解码 cookie 并使用 “:” 分隔符将其拆分为一组令牌字符串。
在这里插入图片描述
由子类实现,整个autoLogin是一个模板方法
在这里插入图片描述

在这里插入图片描述

返回的最终 Authentication 对象在这里插入图片描述

TokenBasedRememberMeServices
校验过期时间->生成签名并与cookieTokens中进行比较
在这里插入图片描述
在这里插入图片描述

PersistentTokenBasedRememberMeServices
默认实现InMemory,还提供了JDBC
在这里插入图片描述

RememberMeAuthenticationFilter

来看看RememberMe的引用
之前也提到过GenericFilterBean,他是Filte的简单基本实现,不处理这个过滤器仅执行一次

public class RememberMeAuthenticationFilter extends GenericFilterBean implements ApplicationEventPublisherAware {
// 成功处理器
	private AuthenticationSuccessHandler successHandler;
// 授权管理器
	private AuthenticationManager authenticationManager;
// 上文提到的记住我服务	
	private RememberMeServices rememberMeServices;
// 策略类
	private SecurityContextRepository securityContextRepository = new NullSecurityContextRepository();
}
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
			// 不为null,说明已经认证过了
		if (SecurityContextHolder.getContext().getAuthentication() != null) {
			this.logger.debug(LogMessage
					.of(() -> "SecurityContextHolder not populated with remember-me token, as it already contained: '"
							+ SecurityContextHolder.getContext().getAuthentication() + "'"));
			chain.doFilter(request, response);
			return;
		}
		Authentication rememberMeAuth = this.rememberMeServices.autoLogin(request, response);
		if (rememberMeAuth != null) {
			// Attempt authenticaton via AuthenticationManager
			try {
			// 授权、认证
				rememberMeAuth = this.authenticationManager.authenticate(rememberMeAuth);
				// Store to SecurityContextHolder
			// 重新设置上下文
				SecurityContext context = SecurityContextHolder.createEmptyContext();
				context.setAuthentication(rememberMeAuth);
			// 之前也提及过,默认是threadLoacl	
				SecurityContextHolder.setContext(context);	
				onSuccessfulAuthentication(request, response, rememberMeAuth);
				this.logger.debug(LogMessage.of(() -> "SecurityContextHolder populated with remember-me token: '"
						+ SecurityContextHolder.getContext().getAuthentication() + "'"));
			// 保存securityContext
				this.securityContextRepository.saveContext(context, request, response);
				if (this.eventPublisher != null) {
					this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
							SecurityContextHolder.getContext().getAuthentication(), this.getClass()));
				}
				if (this.successHandler != null) {
					this.successHandler.onAuthenticationSuccess(request, response, rememberMeAuth);
					return;
				}
			}
			catch (AuthenticationException ex) {
				this.logger.debug(LogMessage
						.format("SecurityContextHolder not populated with remember-me token, as AuthenticationManager "
								+ "rejected Authentication returned by RememberMeServices: '%s'; "
								+ "invalidating remember-me token", rememberMeAuth),
						ex);
				this.rememberMeServices.loginFail(request, response);
				onUnsuccessfulAuthentication(request, response, ex);
			}
		}
		chain.doFilter(request, response);
	}

RememberMeAuthenticationToken

在这里插入图片描述
指示类可以处理特定的 Authentication 实现,策略模式

public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
boolean supports(Class<?> authentication);
}

RememberMeAuthenticationProvider
在这里插入图片描述

RememberMeConfigurer

配置记住我过滤器,核心方法init和configure

在这里插入图片描述
这一步可以设置自己的RememberMeService
在这里插入图片描述

 .and()
                .rememberMe()
                .rememberMeServices(rememberMeServices()) // 设置自动登录时使用rememberServic

SessionManagementFilter

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		if (!this.securityContextRepository.containsContext(request)) {
			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
			// 判断是否为null并且是否匿名
			if (authentication != null && !this.trustResolver.isAnonymous(authentication)) {
				try {
				// 核心方法,策略类
					this.sessionAuthenticationStrategy.onAuthentication(authentication, request, response);
				}
			
				this.securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response);
			}
		}
		chain.doFilter(request, response);
	}

在这里插入图片描述
在这里插入图片描述

RegisterSessionAuthenticationStrategy

用于在成功Authentication后向SessionRegistry用户注册的策略
在这里插入图片描述

SessionRegistry 维护实例注册表 SessionInformatio

List<SessionInformation> getAllSessions(Object principal, boolean includeExpiredSessions);
SessionInformation getSessionInformation(String sessionId);
void refreshLastRequest(String sessionId);
void registerNewSession(String sessionId, Object principal);
void removeSessionInformation(String sessionId);

SessionRegistryImpl(只适合单机)
在这里插入图片描述

ConcurrentSessionControlAuthenticationStrategy

在这里插入图片描述
在这里插入图片描述

CompositeSessionAuthenticationStrategy

通过组合模式将所需要的策略组合在一起
在这里插入图片描述

AbstractSessionFixationProtectionStrategy

让sessionId变换,防止被截取
在这里插入图片描述
在这里插入图片描述

SessionInformation

在这里插入图片描述

SessionInformationExpiredStrategy

确定在 中ConcurrentSessionFilter检测到过期会话时的行为ConcurrentSessionFilter。
在这里插入图片描述
在这里插入图片描述
session过期策略
在这里插入图片描述
重定向策略

在这里插入图片描述在这里插入图片描述

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值