SPRING与设计模式---生成器模式

SPRING与设计模式---生成器模式

使用场景:当一个产品(对象)构造过程很复杂时,使用生成器模式封装产品的构造过程,并允许按步骤构造。

springsecurity4构造FilterChainProxy并添加到容器中的过程

1.使用HttpSecurity构造DefaultSecurityFilterChain就使用到了生成器模式,见UML类图:

SPRING与设计模式---生成器模式_第1张图片

源码:使用FilterComparator对filters进行排序,然后生成DefaultSecurityFilterChain

@Override
protected DefaultSecurityFilterChain performBuild() throws Exception {
   Collections.sort(filters, comparator);
   return new DefaultSecurityFilterChain(requestMatcher, filters);
}

2.最终由WebSecurity使用生成器模式生成FilterChainProxy,并将DefaultSecurityFilterChain注入FilterChainProxy中。

@Override
protected Filter performBuild() throws Exception {
   Assert.state(
         !securityFilterChainBuilders.isEmpty(),
         "At least one SecurityBuilder needs to be specified. Typically this done by adding a @Configuration that extends WebSecurityConfigurerAdapter. More advanced users can invoke "
               + WebSecurity.class.getSimpleName()
               + ".addSecurityFilterChainBuilder directly");
   int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
   List securityFilterChains = new ArrayList(
         chainSize);
   for (RequestMatcher ignoredRequest : ignoredRequests) {
      securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
   }
   for (SecurityBuilderextends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
      securityFilterChains.add(securityFilterChainBuilder.build());
   }
   FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
   if (httpFirewall != null) {
      filterChainProxy.setFirewall(httpFirewall);
   }
   filterChainProxy.afterPropertiesSet();

   Filter result = filterChainProxy;
   if (debugEnabled) {
      logger.warn("\n\n"
            + "********************************************************************\n"
            + "**********        Security debugging is enabled.       *************\n"
            + "**********    This may include sensitive information.  *************\n"
            + "**********      Do not use in a production system!     *************\n"
            + "********************************************************************\n\n");
      result = new DebugFilter(filterChainProxy);
   }
   postBuildAction.run();
   return result;
}

3.WebSecurityConfiguration使用WebSecurity生成FilterChainProxy的注入SPRING容器

@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
public Filter springSecurityFilterChain() throws Exception {
   boolean hasConfigurers = webSecurityConfigurers != null
         && !webSecurityConfigurers.isEmpty();
   if (!hasConfigurers) {
      WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
            .postProcess(new WebSecurityConfigurerAdapter() {
            });
      webSecurity.apply(adapter);
   }
   return webSecurity.build();
}

由于生成器类(都是以Builder结尾的类名)要做的事情很多,而且都不相同,所以有一堆配置器类(以Configurer结尾的类)来完成各个Filter的生成。UML类图见:

SPRING与设计模式---生成器模式_第2张图片

配置代码:

public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    // roles admin allow to access /admin/**
    // roles user allow to access /user/**
    // custom 403 access denied handler
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // fix X-Frame-Options:DENY
        http.headers().frameOptions().disable();

        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/", "/home", "/about",UserSignAuthenticationFilter.USER_SIGN_LOGIN_URL).permitAll()
//                .antMatchers("/admin/**").hasAnyRole("ADMIN")
//                .antMatchers("/user/**").hasAnyRole("USER")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll()
                .and()
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler);

        //自定义身份认证方式,
        http.addFilterBefore(buildUserSignAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        //自定义授权方式
        http.addFilterBefore(buildProtectedUrlFilter(), FilterSecurityInterceptor.class);

    }
 
  
 
  
 
  
 
 

你可能感兴趣的:(架构,设计模式)