SprigSecurityソース学習(一)

11834 ワード

前言
本文はjava配置のSpring Securityソースに基づいて勉強することを討論します。
Servlet 3.0から話す
Servlet 3.0以降は、伝統的なweb.xmlの代わりに、javaベースでservlet容器を配置することを推奨する。
Servlet ContinerInitializer
容器はクラスパスの下でjavax.servlet.Servlet ContinerInitializerインターフェースを実現したクラスを探しています。発見できれば、servlet容器を配置するためにそれを使っています。従来のweb.xmlに代わる機能です。
SpringServlet ContinerInitializer
SpringはServlet標準インターフェースの実現類を提供しています。SpringServletContinerInitializerは、この種の牛逼迫はまた「クラスパス」の下で検索してWebAppliation Initizerインターフェースのすべての種類を実現し、本当に配置されたタスクをそれに委託して実現します。具体的なソースは以下の通りです。パラメータの意味に注意してください。
    /*
     * @param webAppInitializerClasses all implementations of
     * {@link WebApplicationInitializer} found on the application classpath
     * @param servletContext the servlet context to be initialized
     */
    @Override
    public void onStartup(Set> webAppInitializerClasses, ServletContext servletContext) {
                .....
    }
Abstract Security WebAppliation Initializer
このクラスはSpring Securityが提供するWebAppliation Initializerのサブクラスです。主にすることは、Delegating FilterProxyを作成することです。本質的にはフィルタです。デフォルトのname=sprigSecurityFilterChin、urlPatterns=/*。すべての要求はSprigSecurityの処理を経なければならないということです。(静的資源も含みますよ。)
    public final void onStartup(ServletContext servletContext) throws ServletException {
        beforeSpringSecurityFilterChain(servletContext);
        if (this.configurationClasses != null) {
            AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
            rootAppContext.register(this.configurationClasses);
            servletContext.addListener(new ContextLoaderListener(rootAppContext));
        }
        if (enableHttpSessionEventPublisher()) {
            servletContext.addListener(
                    "org.springframework.security.web.session.HttpSessionEventPublisher");
        }
        servletContext.setSessionTrackingModes(getSessionTrackingModes());
        //           Servlet     
        insertSpringSecurityFilterChain(servletContext);
        afterSpringSecurityFilterChain(servletContext);
    }
Delegating FilterProxy
フィルタチェーンエージェントの委任。前に述べたように、それは本質的にFilterであり、すべての要求を遮断している。実はSprigSecurity権限管理の入り口です。Filterである以上、私達はそのdoFilter()がどのように要求を処理しているかを見ます。
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        // Lazily initialize the delegate if necessary.
        Filter delegateToUse = this.delegate;
        if (delegateToUse == null) {
            synchronized (this.delegateMonitor) {
                if (this.delegate == null) {
                    WebApplicationContext wac = findWebApplicationContext();
                    if (wac == null) {
                        throw new IllegalStateException("No WebApplicationContext found: " +
                                "no ContextLoaderListener or DispatcherServlet registered?");
                    }
                    // spring web    name=springSecurityFilterChain bean
                    this.delegate = initDelegate(wac);
                }
                delegateToUse = this.delegate;
            }
        }

        // Let the delegate perform the actual doFilter operation.
        invokeDelegate(delegateToUse, request, response, filterChain);
    }
したがって、ここから見ると、これは確かに「エージェント」であり、要求を受けた後、spring webコンテナのname=sprigSecurityFilterChinのbeanに要求を委任する。
@EnbaleWebSecurityから話します。
javaの配置に基づくSpring Securityには、一般的にこのような構成があります。
@EnableWebSecurity
@ComponentScan("fn.wd.security")
public class SpringSecurityConfiger extends WebSecurityConfigurerAdapter {
    ...
}
@EnbleWebSecurityは実は複合注釈です。
@Import({ WebSecurityConfiguration.class, ObjectPostProcessorConfiguration.class,
        SpringWebMvcImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {}
すみません、@Importはxmlプロファイルと似ています。後者は他の構成ファイル(xml)を導入するためのものです。前者は他の構成クラス(.class)を導入するためのものです。このことから分かるように、この注釈は実は3つの構成類を導入しています。
Object PostProcessorConfigration
導入された配置クラスの一つは簡単で、AutowireBenFactory Object PostProcessorを作成しました。
    @Bean
    public ObjectPostProcessor objectPostProcessor(
            AutowireCapableBeanFactory beanFactory) {
        return new AutowireBeanFactoryObjectPostProcessor(beanFactory);
    }
AutowireBeanFactory Object PostProcessor
Object PostProcessorの1つの実装クラスであり、手動でオブジェクトを作成した後(一般的には手動でnew xxx()を指し、このバックプロセッサを使って、手動で作成したクラスのために注入に依存する機能を果たす。
例を挙げます
    Class A implements BeanFactoryAware{
        private BeanFactory beanFactory;

        public void setBeanFactory(BeanFactory beanFactory){
            this.beanFactory=beanFactory;
        }

        ...
    }

    Class App{
        public static void main(String[] args){
            //a      ,      BeanFactoryAware,  Spring      
            A a=new A();

            //              
            autowireBeanFactoryObjectPostProcessor.process(a);

            //  a    spring        

        }
    }
この類はやはり重要です。後はよく使います。この類については、何をするかを知るといいです。
SpringWebMvcImportSelector
導入された配置類の一つは、現在SprigMVC環境であるかどうかを判断することも簡単です。(DispacherServletがクラスパスではないかを見てください。)もしそうであれば、SprigMVCの配置類を導入します。WebMvc SecurityConfigration。
WebSecurityConfigration
導入された設定クラスの一つ。これはSpring Security全体の配置類です。何をしましたか?
1)AutowiredWebSecurityConfigrers IgnorePartsを作成する
AutowiredWebSecurityConfignorePartsオブジェクトを作成し、コンテナに入れます。
@Bean
public AutowiredWebSecurityConfigurersIgnoreParents autowiredWebSecurityConfigurersIgnoreParents(
            ConfigurableListableBeanFactory beanFactory) {
        return new AutowiredWebSecurityConfigurersIgnoreParents(beanFactory);
    }
この種類は何をするものですか?Spring Webコンテナにあるすべてのタイプを取得するのはWebSecurityConfigrerのbeanです。ソースは以下の通りです
public ListFilter, WebSecurity>> getWebSecurityConfigurers() {
        ListFilter, WebSecurity>> webSecurityConfigurers = new ArrayListFilter, WebSecurity>>();
        Map<String, WebSecurityConfigurer> beansOfType = beanFactory
                .getBeansOfType(WebSecurityConfigurer.class);
        for (Entry<String, WebSecurityConfigurer> entry : beansOfType.entrySet()) {
            webSecurityConfigurers.add(entry.getValue());
        }
        return webSecurityConfigurers;
    }
2)FilterChinProxyのビルダーを設置する
スプリングwebコンテナの「フィルタチェーンエージェント」のすべての「構成器」を取得し、「フィルタチェーンエージェント」の「ビルダー」に設定します。
@Autowired(required = false)
public void setFilterChainProxySecurityConfigurer(
            ObjectPostProcessor objectPostProcessor,
@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List> webSecurityConfigurers)
            throws Exception {
            ...
}
注意:ここにはspelの高次の使い方があります。
@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}")
コンテナのname=autwiredWebSecurityConfignorers Ignorepartsのbeanオブジェクトを取得し、それをget WebSecurityConfigrers()の戻り値にweb SecurityConfigrers属性に注入するという意味です。
3)フィルタチェーンの作成エージェント
前に述べたように、「フィルタチェーンエージェントのデリゲート」フィルタは、受け取った要求を「フィルタチェーンエージェント」に転送して処理しますが、このフィルタチェーンエージェントはどこで作成されましたか?承諾します。ここで作成したbeanのnameは、sprigSecurityFilterChinです。
    @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();
    }