概述
介绍
WebSecurityConfigurerAdapter是Spring Security Config内置提供的一个WebSecurityConfigurer抽象实现类。WebSecurityConfigurerAdapter存在的目的是提供一个方便开发人员配置WebSecurity的基类。它提供了一组全方位配置WebSecurity的缺省方法实现。开发人员只要继承WebSecurityConfigurerAdapter提供自己的实现类,哪怕不覆盖WebSecurityConfigurerAdapter的任何一个方法,都得到了一个配置WebSecurity的安全配置器WebSecurityConfigurer实例。但通常情况下,开发人员都有自己特定的安全配置和要求,这时候就可以在自己提供的WebSecurityConfigurerAdapter子实现类中提供自己的方法覆盖WebSecurityConfigurerAdapter相应的方法从而对WebSecurity实施定制。
WebSecurityConfigurerAdapter为开发人员提供了如下功能 :
1.构建一个用于配置WebSecurity的WebSecurityConfigurerAdapter对象,可以指定使用或者不使用缺省配置,默认构造函数使用缺省配置;
2.提供可覆盖实现的方法void configure(AuthenticationManagerBuilder auth) ,允许开发人员配置目标WebSecurity所使用的AuthenticationManager的双亲AuthenticationManager;该方法缺省实现的效果是该双亲AuthenticationManager来自AuthenticationConfiguration定义的AuthenticationManager(其实是来自IoC容器的类型为AuthenticationManager的一个bean);
通过覆盖实现该方法,开发人员可以定制认证机制,比如设置成基于内存的认证,基于数据库的认证,基于LDAP的认证,甚至这些认证机制的一个组合,设置AuthenticationManager的双亲关系,所使用的PasswordEncoder等等;
3. 提供可覆盖实现的空方法void configure(WebSecurity web),允许开发人员覆盖实现配置WebSecurity,比如设置哪些URL要忽略安全等等;
通过覆盖实现该方法,开发人员可以定制WebSecurity,主要是除了HttpSecurity之外的安全控制,比如忽略某些静态公开资源或者动态公开资源的安全 ,设置需要使用的防火墙实例,设置权限评估器,安全表达式处理器等;
4.WebSecurityConfigurerAdapter自身是一个WebSecurityConfigurer,它在自己的初始化方法init()中创建了HttpSecurity http安全构建器对象,并在缺省情况下(disableDefaults为false)应用了如下HttpSecurity初始配置:
http.csrf().and() // 应用 CsrfConfigurer.addFilter(new WebAsyncManagerIntegrationFilter()) // 添加过滤器 WebAsyncManagerIntegrationFilter.exceptionHandling().and() // 应用 ExceptionHandlingConfigurer.headers().and() // 应用 HeadersConfigurer.sessionManagement().and() // 应用 SessionManagementConfigurer.securityContext().and() // 应用 SecurityContextConfigurer.requestCache().and() // 应用 RequestCacheConfigurer.anonymous().and() // 应用 AnonymousConfigurer.servletApi().and() // 应用 ServletApiConfigurer.apply(new DefaultLoginPageConfigurer<>()).and() // 应用 DefaultLoginPageConfigurer.logout(); // 应用 LogoutConfigurer// 使用 SpringFactoriesLoader 加载 classpath 上所有jar包中各自的 META-INF/spring.factories 属性文件// 中指定的 AbstractHttpConfigurer,应用到 httpClassLoader classLoader = this.context.getClassLoader();List<AbstractHttpConfigurer> defaultHttpConfigurers =SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {http.apply(configurer);}
5.提供可覆盖实现的空方法void configure(HttpSecurity http),允许开发人员配置目标HttpSecurity;这里该方法缺省的实现对HttpSecurity的安全配置如下:
对任何请求要求用户已认证(通俗地讲,用户必须先登录才能访问任何资源);
启用用户名密码表单登录认证机制;
启用Http Basic认证机制;
通过覆盖实现该方法,开发人员可以定制HttpSecurity;
http.authorizeRequests().anyRequest().authenticated().and()// 上面行应用一个 ExpressionUrlAuthorizationConfigurer,要求所有URL必须登录认证后才能访问.formLogin().and() // 应用 FormLoginConfigurer.httpBasic(); // 应用 HttpBasicConfigurer
WebSecurityConfigurerAdapter
WebSecurityConfigurerAdapter提供了简洁方式来创建WebSecurityConfigurer,其作为基类,可通过实现该类自定义配置类。其自动从SpringFactoriesLoader查找AbstractHttpConfigurer让我们去扩展,想要实现必须创建一个AbstractHttpConfigurer的扩展类
其源码分析:
//1.init初始化:获取HttpSecurity和配置FilterSecurityInterceptor拦截器到WebSecuritypublic void init(final WebSecurity web) throws Exception {//获取HttpSecurityfinal HttpSecurity http = getHttp();//配置FilterSecurityInterceptor拦截器到WebSecurityweb.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {public void run() {FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);web.securityInterceptor(securityInterceptor);}});}......//2.获取HttpSecurity的过程protected final HttpSecurity getHttp() throws Exception {if (http != null) {return http;}DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor.postProcess(new DefaultAuthenticationEventPublisher());localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);AuthenticationManager authenticationManager = authenticationManager();authenticationBuilder.parentAuthenticationManager(authenticationManager);Map<Class<? extends Object>, Object> sharedObjects = createSharedObjects();http = new HttpSecurity(objectPostProcessor, authenticationBuilder,sharedObjects);if (!disableDefaults) {// 默认的HttpSecurity的配置http//添加 CSRF 支持,使用WebSecurityConfigurerAdapter时,默认启用,禁用csrf().disable().csrf().and()//添加WebAsyncManagerIntegrationFilter.addFilter(new WebAsyncManagerIntegrationFilter())//允许配置异常处理.exceptionHandling().and()//将安全标头添加到响应.headers().and()//允许配置会话管理.sessionManagement().and()//HttpServletRequest之间的SecurityContextHolder创建securityContext管理.securityContext().and()//允许配置请求缓存.requestCache().and()//允许配置匿名用户.anonymous().and()//HttpServletRequestd的方法和属性注册在SecurityContext中.servletApi().and()//使用默认登录页面.apply(new DefaultLoginPageConfigurer<>()).and()//提供注销支持.logout();// @formatter:onClassLoader classLoader = this.context.getClassLoader();List<AbstractHttpConfigurer> defaultHttpConfigurers =SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);for(AbstractHttpConfigurer configurer : defaultHttpConfigurers) {http.apply(configurer);}}configure(http);return http;}...//3.可重写方法实现自定义的HttpSecurityprotected void configure(HttpSecurity http) throws Exception {logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();}....
从源码init初始化模块中的“获取HttpSecurity”和“配置FilterSecurityInterceptor拦截器到WebSecurity”中可以看出,想要spring Security如何知道我们要求所有用户都经过身份验证?Spring Security如何知道我们想要支持基于表单的身份验证?只要重写protected void configure(HttpSecurity http) throws Exception方法即可。因此我们需要理解HttpSecurity的方法的作用
HttpSecurity
HttpSecurity基于Web的安全性允许为特定的http请求进行配置。其有很多方法,列举一些常用的如下表:

HttpSecurity还有很多方法供我们使用,去配置HttpSecurity。
由于太多这边就不一一说明,有兴趣可去研究。




