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逻辑

其实就两步,第一调用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来做,具体实现是这样的

提供多个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

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

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

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值