Spring Security授权过程

本文深入剖析Spring Security的授权过程,从UsernamePasswordAuthenticationFilter到FilterSecurityInterceptor,详细讲解了AccessDecisionManager如何进行权限决策,包括WebExpressionVoter的投票机制。通过对源码和时序图的分析,揭示了Spring Security如何确保用户有权访问资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言


本文是接上一章Spring Security源码分析一:Spring Security认证过程进一步分析Spring Security用户名密码登录授权是如何实现得;

类图

在这里插入图片描述

源码分析


如图所示,显示了登录认证过程中的 filters相关的调用流程,作者将几个自认为重要的 filters 标注了出来
在这里插入图片描述
从图中可以看出执行的顺序。来看看几个作者认为比较重要的Filter 的处理逻辑,UsernamePasswordAuthenticationFilterAnonymousAuthenticationFilterExceptionTranslationFilterFilterSecurityInterceptor以及相关的处理流程如下所述;

UsernamePasswordAuthenticationFilter


整个调用流程是,先调用其父类 AbstractAuthenticationProcessingFilter.doFilter() 方法,然后再执行 UsernamePasswordAuthenticationFilter.attemptAuthentication() 方法进行验证;

AbstractAuthenticationProcessingFilter

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
   

		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		#1.判断当前的filter是否可以处理当前请求,不可以的话则交给下一个filter处理
		if (!requiresAuthentication(request, response)) {
   
			chain.doFilter(request, response);

			return;
		}

		if (logger.isDebugEnabled()) {
   
			logger.debug("Request is to process authentication");
		}

		Authentication authResult;

		try {
   
			#2.抽象方法由子类UsernamePasswordAuthenticationFilter实现
			authResult = attemptAuthentication(request, response);
			if (authResult == null) {
   
				// return immediately as subclass has indicated that it hasn't completed
				// authentication
				return;
			}
			#2.认证成功后,处理一些与session相关的方法 
			sessionStrategy.onAuthentication(authResult, request, response);
		}
		catch (InternalAuthenticationServiceException failed) {
   
			logger.error(
					"An internal error occurred while trying to authenticate the user.",
					failed);
			#3.认证失败后的的一些操作
			unsuccessfulAuthentication(request, response, failed);

			return;
		}
		catch (AuthenticationException failed) {
   
			// Authentication failed
			unsuccessfulAuthentication(request, response, failed);

			return;
		}

		// Authentication success
		if (continueChainBeforeSuccessfulAuthentication) {
   
			chain.doFilter(request, response);
		}
		#3. 认证成功后的相关回调方法 主要将当前的认证放到SecurityContextHolder中
		successfulAuthentication(request, response, chain, authResult);
	}

整个程序的执行流程如下:

  1. 判断filter是否可以处理当前的请求,如果不可以则放行交给下一个filter
  2. 调用抽象方法attemptAuthentication进行验证,该方法由子类UsernamePasswordAuthenticationFilter实现
  3. 认证成功以后,回调一些与 session相关的方法;
  4. 认证成功以后,认证成功后的相关回调方法;认证成功以后,认证成功后的相关回调方法;
protected void successfulAuthentication(HttpServletRequest request,
         HttpServletResponse response, FilterChain chain, Authentication authResult)
         throws IOException, ServletException {
   

     if (logger.isDebugEnabled()) {
   
         logger.debug("Authentication success. Updating SecurityContextHolder to contain: "
                 + authResult);
     }

     SecurityContextHolder.getContext().setAuthentication(authResult);

     rememberMeServices.loginSuccess(request, response, authResult);

     // Fire event
     if (this.eventPublisher != null) {
   
         eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
                 authResult, this.getClass()));
     }

     successHandler.onAuthenticationSuccess
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值