UsernameAuthenticationFilter授权成功后调用AuthenticationSuccessHandler时的解析

1、问题

AuthenticationSuccessHandler处理中的Authentication是什么,与传入AuthenticationManager#authenticate(Authentication authentication)中的 Authentication是一样的吗

2、分析

UsernameAuthenticationFilter中调用AuthenticationManager#authenticate,其实调用的是DaoAuthenticationProvider的authenticate,在其父类AbstractUserDetailsAuthenticationProvider中定义了处理模板。其处理代码如下

public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		
	String username = determineUsername(authentication);
	boolean cacheWasUsed = true;
	UserDetails user = this.userCache.getUserFromCache(username);
	if (user == null) {
		cacheWasUsed = false;
		
		user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
		
	}
	
	this.preAuthenticationChecks.check(user);
	additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
	
	this.postAuthenticationChecks.check(user);
	if (!cacheWasUsed) {
		this.userCache.putUserInCache(user);
	}
	Object principalToReturn = user;
	if (this.forcePrincipalAsString) {
		principalToReturn = user.getUsername();
	}
	return createSuccessAuthentication(principalToReturn, authentication, user);
}

principalToReturn为retrieveUser返回的。DaoAuthenticationProvider的retrieveUser是通过UserDetailsService#loadUserByUserName得到UserDetails。

protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
	prepareTimingAttackProtection();
	
	UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);
	if (loadedUser == null) {
		throw new InternalAuthenticationServiceException(
				"UserDetailsService returned null, which is an interface contract violation");
	}
	return loadedUser;
	}
}

然后创建新的Authentication,即以UserDetails作为principal。

protected Authentication createSuccessAuthentication(Object principal, Authentication authentication,
			UserDetails user) {
		// Ensure we return the original credentials the user supplied,
		// so subsequent attempts are successful even with encoded passwords.
		// Also ensure we return the original getDetails(), so that future
		// authentication events after cache expiry contain the details
		UsernamePasswordAuthenticationToken result = UsernamePasswordAuthenticationToken.authenticated(principal,
				authentication.getCredentials(), this.authoritiesMapper.mapAuthorities(user.getAuthorities()));
		result.setDetails(authentication.getDetails());
		this.logger.debug("Authenticated user");
		return result;
	}

3、结论

AuthenticationSuccessHandler中的 authentication与AuthenticationManager#authenticate传入的不一样,AuthenticationSuccessHandler中的authentication是由UserDetails作为principal,AuthenticationManager#authenticate传入的authentication的credentials作为新authentication的credentials

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值