spring security 入门流程源码讲解

spring security4.x 入门流程源码讲解

1.AbstractAuthenticationProcessingFilter 抽象的authencationProcessingFilter 用于过滤验证是否需要拦截以及认证

(1).首先查看doFilter方法

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

				HttpServletRequest request = (HttpServletRequest) req;
				HttpServletResponse response = (HttpServletResponse) res;
				//判断请求是否需要拦截
				if (!requiresAuthentication(request, response)) {
					chain.doFilter(request, response);

					return;
				}

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

				Authentication authResult;

				try {
					//预身份验证,由子类 UsernamePasswordAuthenticationFilter 实现执行
					authResult = attemptAuthentication(request, response);
					if (authResult == null) {
						// return immediately as subclass has indicated that it hasn't completed
						// authentication
						return;
					}
					sessionStrategy.onAuthentication(authResult, request, response);
				}
				catch (InternalAuthenticationServiceException failed) {
					logger.error(
							"An internal error occurred while trying to authenticate the user.",
							failed);
					unsuccessfulAuthentication(request, response, failed);

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

					return;
				}

				// Authentication success
				if (continueChainBeforeSuccessfulAuthentication) {
					chain.doFilter(request, response);
				}
		    
				successfulAuthentication(request, response, chain, authResult);
			}
2.1UsernamePasswordAuthenticationFilter 他是AbstractAuthenticationProcessingFilter过滤器的实现。但是他还不是执行验证逻辑的过滤器!
public Authentication attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws AuthenticationException {
		//判断是否是post请求
		if (postOnly && !request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException(
					"Authentication method not supported: " + request.getMethod());
		}

		String username = obtainUsername(request);
		String password = obtainPassword(request);

		if (username == null) {
			username = "";
		}

		if (password == null) {
			password = "";
		}

		username = username.trim();
		
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				username, password);

		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);
		//此时真实的验证由AuthenticationProvider的实现AbstractUserDetailsAuthenticationProvider的	authenticate(Authentication authentication)方法执行验证逻辑      AuthenticationProvider会有很多不同provider,可以自定义实现自己的provider   例如除了帐号和密码验证之外还有验证码,此时就需要继承AuthenticationProvider实现自定义provider。
		return this.getAuthenticationManager().authenticate(authRequest);
	}
2.2验证失败调用AbstractAuthenticationProcessingFilter 的unsuccessfulAuthentication(HttpServletRequest request,HttpServletResponse response, AuthenticationException failed) 方法 失败可以自定义failureHandler 用于自定义返回值
	protected void unsuccessfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, AuthenticationException failed)
			throws IOException, ServletException {
		SecurityContextHolder.clearContext();

		if (logger.isDebugEnabled()) {
			logger.debug("Authentication request failed: " + failed.toString(), failed);
			logger.debug("Updated SecurityContextHolder to contain null Authentication");
			logger.debug("Delegating to authentication failure handler " + failureHandler);
		}

		rememberMeServices.loginFail(request, response);

		failureHandler.onAuthenticationFailure(request, response, failed);
	}
2.3验证成功调用AbstractAuthenticationProcessingFilter 的successfulAuthentication(HttpServletRequest request,HttpServletResponse response, FilterChain chain, Authentication authResult) 方法 ,认证成功主要内容为:把认证信息存入SecurityContextHolder;通知认证成功给用户。同样我们可以自定义successHandler,返回JSON返回XML,
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(request, response, authResult);
	}
注意: 到这里整改认证过程就执行完了,后续会补入一个流程图,让大家看的更清晰,下次再讲授权关于授权流程。

可以关注下博主的公众号,实时推送解决方案!
公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值