Spring Security系列-Spring Security运行机制分析(四)

前言

前面三篇写的关于Spring Security是如何进行用户认证,本篇来看看我们输入的用户名和密码是如何传给AuthenticationManager的。

Filter

Spring Security有一个FilterChain,它包含由多个Filter组成的集合。当用户输入用户密码,并提交HttpRequest后,Spring Security通过一系列的Filter对HttpRequest进行处理和筛选。下面的图可以看出,Spring Security Filter Chain 作为Servlet Filter中的一个,但它包含了多个Filter。
在这里插入图片描述

Configurer

在org.springframework.security.config.annotation.web.configurers包下有许多configurer类。这些configurer类,都实现了configurer方法。当Spring Security初始化时,会根据代码中定义的Configurer配置或者properties文件中的配置,得到一个Configurer集合。集合中的每个Configurer类中的configurer方法被调用时,就可往SecurityFilterChain中添加相应的Filter。

之前在Spring Security系列-Spring Security简单身份认证配置(二)中配置了的身份认证,它所使用的Configure以及生成的Filter如下:

FiltersConfigurers
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilterWebSecurityConfigurerAdapter直接添加
org.springframework.security.web.context.SecurityContextPersistenceFilterSecurityContextConfigurer
org.springframework.security.web.header.HeaderWriterFilterHeadersConfigurer
org.springframework.security.web.csrf.CsrfFilterCsrfConfigurer
org.springframework.security.web.authentication.logout.LogoutFilterLogoutConfigurer
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilterFormLoginConfigurer
org.springframework.security.web.savedrequest.RequestCacheAwareFilterRequestCacheConfigurer
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilterServletApiConfigurer
org.springframework.security.web.authentication.AnonymousAuthenticationFilterAnonymousConfigurer
org.springframework.security.web.session.SessionManagementFilterCsrfCoSessionManagementConfigurerfigurer
org.springframework.security.web.access.ExceptionTranslationFilterExceptionHandlingConfigurer
org.springframework.security.web.access.intercept.FilterSecurityInterceptorExpressionUrlAuthorizationConfigurer

Configurer中添加Filter

下面是调用每个Configurer中的configure方法

public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
		extends AbstractSecurityBuilder<O> {
	private void configure() throws Exception {
		Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

		for (SecurityConfigurer<O, B> configurer : configurers) {
			configurer.configure((B) this);
		}
	}
}

下面是类WebSecurityConfigurerAdapter中,加载默认的配置

http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
		sharedObjects);
if (!disableDefaults) {
	// @formatter:off
	http
		.csrf().and()
		.addFilter(new WebAsyncManagerIntegrationFilter())
		.exceptionHandling().and()
		.headers().and()
		.sessionManagement().and()
		.securityContext().and()
		.requestCache().and()
		.anonymous().and()
		.servletApi().and()
		.apply(new DefaultLoginPageConfigurer<>()).and()
		.logout();
	// @formatter:on
	ClassLoader classLoader = this.context.getClassLoader();
	List<AbstractHttpConfigurer> defaultHttpConfigurers =
			SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);

	for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
		http.apply(configurer);
	}
}

UsernamePasswordAuthenticationFilter

从UsernamePasswordAuthenticationFilter类中的,attemptAuthentication方法可以看到使用了AuthenticationManager的authenticate方法来验证HttpRequest中的username和password。看过上篇的读者应该记得,上篇我们的通过控制台输入的用户密码,然后进行验证,也是通过这种方式运行的。

public Authentication attemptAuthentication(HttpServletRequest request,
		HttpServletResponse response) throws AuthenticationException {
	if (postOnly && !request.getMethod().equals("POST")) {
		throw new AuthenticationServiceException(
				"Authentication method not supported: " + request.getMethod());
	}

	String username = obtainUsername(request);
	String password = obtainPassword(request);

	if (username == null) {
		username = "";
	}

	if (password == null) {
		password = "";
	}

	username = username.trim();

	UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
			username, password);

	// Allow subclasses to set the "details" property
	setDetails(request, authRequest);

	return this.getAuthenticationManager().authenticate(authRequest);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值