public UsernamePasswordAuthenticationToken(Object principal,Object credentials){ n super(null);n this.principal=principal;n this.credentials=credentials;n //还没认证n setAuthenticated(false);n}n
/**n * Indicates a class can process a specific Authentication n **/npublic interface AuthenticationProvider { n Authentication authenticate(Authentication authentication)n throws AuthenticationException;n //支不支持特定类型的authenticationn boolean supports(Class<?> authentication);n}n
String presentedPassword = authentication.getCredentials().toString(); if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { logger.debug("Authentication failed: password does not match stored value"); throw new BadCredentialsException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); }
需要主要的是请求中的密码是被加密过的,所以从数据库获取到的密码也应该是被加密的
注意到当完成校验的时候会把信息放入缓存
//当没有从缓存中获取到值时
,这个字段会被设置成false if (!cacheWasUsed) { this.userCache.putUserInCache(user); } //下次进来的时候回去获取 UserDetails user = this.userCache.getUserFromCache(username);
UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(n principal, authentication.getCredentials(),n authoritiesMapper.mapAuthorities(user.getAuthorities()));n result.setDetails(authentication.getDetails());n
public UsernamePasswordAuthenticationToken(Object principal, Object credentials,n Collection<? extends GrantedAuthority> authorities) { n super(authorities);n this.principal = principal;n this.credentials = credentials;n super.setAuthenticated(true); // must use super, as we overriden }n
这次往supe里放了权限集合
,父类的处理是判断里边的权限有没有空的,没有则转换为只读集合
for (GrantedAuthority a : authorities) { n if (a == null) { n throw new IllegalArgumentException(n "Authorities collection cannot contain any null elements");n }n}nArrayList<GrantedAuthority> temp = new ArrayList<>(nauthorities.size());ntemp.addAll(authorities);nthis.authorities = Collections.unmodifiableList(temp);n
收尾工作
回到ProviderManager里的authenticate方法,当我们终于从
result = provider.authenticate(authentication);n
走出来时,后边还有什么操作
将返回的用户信息负责给当前的上下文
if (result != null) { n tcopyDetails(authentication, result);n tbreak;n }n