在项目中实际使用Spring Security时,我们的大部分工作其实都是配置HttpSecurity。要么通过spring的 http xml element 来配置,要么通过配置类里的HttpSecurity class来配置,所以在理解了DelegatingFilterProxy,FilterChainProxy,SecurityFilterChain之间的关系之后就很有必要了解一下HttpSecurity类了。
HttpSecurity这个类的名称与它的实际功用相差甚远,其实把它称为HttpSecurityFilterChainBuiler应该更合适,因为它的作用就是利用构造器模式构造出SecurityFilterChain的一个实例供FilterChainProxy使用。这点从它的类签名就能看出来。
如果有多个 SecurityFilterChain 被配置、构造出来,它们的顺序可以通过注解 @Order来设定。没有@Order注解的优先级最低。同一order层级的,就可以通过 SecurityFilterChain 中的RequestMatcher 来决定了该chain是否与http request匹配了。我们应该尽量把特殊的匹配放在前面,通用的放在后面。
虽然现在基于Spring的开发都是基于注解的了,但是如果遇到遗留系统里通过http元素来定义HttpSecurity,那么俯视一下下面的schema应该也能大致了然了......
看看与 authentication 相关的两个fitler的构建。 1)从两个filter看规律 Filter都是根据Configurer构建出来的。我们以BasicAuthenticationFilter和UsernamePasswordAuthenticationFilter的Configurer举例。 FormLoginConfigurer 比较“特殊”,它定义了两个filter。一个是UsernamePasswordAuthenticationFilter, 一个是DefaultLoginPageGeneratingFilter,后者提供了一个让用户输入credential页面的filter。
public FormLoginConfigurer<HttpSecurity> formLogin() throws Exception {
return getOrApply(new FormLoginConfigurer<>());
}
public HttpBasicConfigurer<HttpSecurity> httpBasic() throws Exception {
return getOrApply(new HttpBasicConfigurer<>());
}
FormLoginConfigurer 是 AbstractAuthenticationFilterConfigurer 的子类,
HttpBasicConfigurer是AbstractHttpConfigurer。这是因为basic的认证方式比起form形式的认证要简单得多。
public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends
AbstractAuthenticationFilterConfigurer<H, FormLoginConfigurer<H>, UsernamePasswordAuthenticationFilter> {
public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecurityBuilder<B>, T extends AbstractAuthenticationFilterConfigurer<B, T, F>, F extends AbstractAuthenticationProcessingFilter>
extends AbstractHttpConfigurer<T, B> {
public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>> extends AbstractHttpConfigurer<HttpBasicConfigurer<B>, B> {
负责根据这些configuer构造出对象来的类是AbstractConfiguredSecurityBuilder。
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>> extends AbstractSecurityBuilder<O> {
在Spring Security 的源码里没有看到 AuthenticationFilter 被使用。这是要让程序员通过提供自定义的 authenticationConverter 和 authenticationManagerResolver 来使用吧。 对比三个与authentication相关的fitler体会下。
BasicAuthenticationFilter:
UsernamePasswordAuthenticationFitler
AuthenticationFilter
下一篇聊下Spring Security里与认证相关classes的逻辑关系。
References: [1]: https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#jc-httpsecurity [2]: https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#_multiple_httpsecurity [3]: https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#jc-custom-dsls [4]: https://www.baeldung.com/spring-onceperrequestfilter
References: [1]: https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#jc-httpsecurity [2]: https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#_multiple_httpsecurity [3]: https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#jc-custom-dsls