云记
首页
常用软件
操作系统
技术分享
东云生态
  • 技术网站
  • 其他
关于我们
首页
常用软件
操作系统
技术分享
东云生态
  • 技术网站
  • 其他
关于我们
  • 前端技术

    • JavaScript基础知识
    • 其他
    • 正则表达式
    • Favicon
  • 后端技术

    • 数据结构
    • 开发规范
    • 路径匹配规则
    • Java字符串
    • 二维码的生成与读取
    • 雪花算法
    • SpringBoot注解
    • SpringBoot自定义banner
    • SpringBoot日志
    • Util、POJO、domain、entity、model、dao、view、mapper、service、controller的作用和区别分析
    • SpringSecurity
  • 数据库

    • MySQL
    • Oracle
  • 面试

    • Java面试

SpringSecurity是如何验证用户的?

  1. 首先调用login接口,传入登录用户名和密码;
  2. LoginController:
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(用户名, 密码);
Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
  1. 上述第二句调用WebSecurityConfigurerAdapter的authenticate方法,执行到return this.delegate.authenticate(authentication),this.delegate即AuthenticationManager接口,ProviderManager实现了该接口(authenticate);
  2. 跳转到ProviderManager继续执行,result = provider.authenticate(authentication)调用AbstractUserDetailsAuthenticationProvider的authenticate方法;
  3. AbstractUserDetailsAuthenticationProvider的authenticate执行user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
  4. 进入到DaoAuthenticationProvider的retrieveUser方法,执行UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);
  5. 此时会调用我们自定义的UserDetailsService中的loadUserByUsername方法从数据库获取用户信息,并写入UserDetails中;

实际的密码校验逻辑是在类DaoAuthenticationProvider的additionalAuthenticationChecks中

@Override
@SuppressWarnings("deprecation")
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
	if (authentication.getCredentials() == null) {
		this.logger.debug("Failed to authenticate since no credentials provided");
		throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
	}
	String presentedPassword = authentication.getCredentials().toString();
	if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
		this.logger.debug("Failed to authenticate since password does not match stored value");
		throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
	}
}

处理登录异常是在这里跳转(类ExceptionTranslationFilter):

private void handleSpringSecurityException(HttpServletRequest request, HttpServletResponse response, FilterChain chain, RuntimeException exception) throws IOException, ServletException {
	if (exception instanceof AuthenticationException) {
		handleAuthenticationException(request, response, chain, (AuthenticationException) exception);
	}else if (exception instanceof AccessDeniedException) {
		handleAccessDeniedException(request, response, chain, (AccessDeniedException) exception);
	}
}
最后更新时间:
贡献者: xiaozhe
上一篇
Util、POJO、domain、entity、model、dao、view、mapper、service、controller的作用和区别分析