Springboot Cas 认证的源码解析

上面文章介绍了Springboot如何集成Cas的认证,但是在写代码的时候有一些疑问:

1)我们获取认证的内容的时候是SecurityContextHolder.getContext(),那么这里面的内容是什么时候放进去的,放进去的内容是什么?

2)我们自定义的userDetailService获取的结果是如何使用的,跟Authentication有什么关系?

下面带着这两个问题,跟着源码的流程往下看,源码可能跟SpringSecurity的版本有关系,我看的版本是4.2.3的

1>CasAuthenticationFilter

主要的类是CasAuthenticationFilter,他的定义如下

public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
}

首先它是继承AbstractAuthenticationProcessingFilter这个类的,我们看AbstractAuthenticationProcessingFilter这个类的filter逻辑

Springboot Cas 认证的源码解析_第1张图片

其实就两步,第一调用attemptAuthentication尝试认证,第二步拿到认证的结果作为参数,执行认证成功之后的流程;这两个步骤分别在子类中CasAuthenticationFilter进行具体的实现;

2>attemptAuthentication的逻辑

@Override
	public Authentication attemptAuthentication(final HttpServletRequest request,
			final HttpServletResponse response) throws AuthenticationException,
			IOException {
		// if the request is a proxy request process it and return null to indicate the
		// request has been processed
		if (proxyReceptorRequest(request)) {
			logger.debug("Responding to proxy receptor request");
			CommonUtils.readAndRespondToProxyReceptorRequest(request, response,
					this.proxyGrantingTicketStorage);
			return null;
		}

		final boolean serviceTicketRequest = serviceTicketRequest(request, response);
		final String username = serviceTicketRequest ? CAS_STATEFUL_IDENTIFIER
				: CAS_STATELESS_IDENTIFIER;
		String password = obtainArtifact(request);

		if (password == null) {
			logger.debug("Failed to obtain an artifact (cas ticket)");
			password = "";
		}

		final UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				username, password);

		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));

		return this.getAuthenticationManager().authenticate(authRequest);
	}

这里具体的认证逻辑并没有,实现是在最后一句

this.getAuthenticationManager().authenticate(authRequest);

具体的认证逻辑在AuthenticationManager来做,具体实现是这样的

Springboot Cas 认证的源码解析_第2张图片

提供多个provider去认证;而对于cas来说,使用的是CasAuthenticationProvider;

3>CasAuthenticationProvider的主要逻辑

private CasAuthenticationToken authenticateNow(final Authentication authentication)
			throws AuthenticationException {
		try {
			final Assertion assertion = this.ticketValidator.validate(authentication
					.getCredentials().toString(), getServiceUrl(authentication));
			final UserDetails userDetails = loadUserByAssertion(assertion);
			userDetailsChecker.check(userDetails);
			return new CasAuthenticationToken(this.key, userDetails,
					authentication.getCredentials(),
					authoritiesMapper.mapAuthorities(userDetails.getAuthorities()),
					userDetails, assertion);
		}
		catch (final TicketValidationException e) {
			throw new BadCredentialsException(e.getMessage(), e);
		}
	}

这里拿ticketValidator.validate 去校验cas的ticket,校验成功之后,这个值作为CasAuthenticationToken中的一个属性,返回的结果是

CasAuthenticationToken;同时loadUserByAssertion会使用我们定义的userDetailService获取一些用户信息,也作为CasAuthenticationToken的属性;

到这里认证完成,我们接着看认证成功之后的流程,回到最开始CasAuthenticationFilter的逻辑

4>successfulAuthentication

Springboot Cas 认证的源码解析_第3张图片

其实重要的逻辑在这里,上面认证的结果,CasAuthenticationToken放在SecurityContext中;到此整个逻辑结束了;

上面的两个疑问也就解决了;

 

 

 

 

你可能感兴趣的:(基础知识,springboot,源码解析)