AbstractSecurityWebApplicationInitializer与AbstractAnnotationConfigDispatcherServletInitializer

Ric*_*ick 8 java spring spring-mvc spring-security

我正在尝试为基于Spring 3.2.8的纯Java配置应用程序添加安全性.我按照说明http://docs.spring.io/spring-security/site/docs/3.2.2.RELEASE/reference/htmlsingle/#jc

我已经完成了3.1节,文档说此时每个URL都需要身份验证,但没有一个(至少我可以加载每个URL).它说它创建了一个Servlet过滤器等.

很明显,WebSecurityConfigurerAdapter子类本身是不够的.所以我看一下3.1.1节,它说下一步是将springSecurityFilterChain注册到WAR,然后继续说明在Servlet 3+环境中,我需要继承AbstractSecurityWebApplicationInitializer.但我已经在继承AbstractAnnotationConfigDispatcherServletInitializer.我应该有一个吗?在AbstractSecurityWebApplicationInitializer JavaDoc中有一些关于排序的讨论,暗示我应该有多个初始化类.

在所有这些中,它还说要将WebSecurityConfigurerAdapter子类添加到getRootConfigClasses()(尽管该示例没有显示其他Spring启动文档的"AppConfig";而且,仅此一项还不够).

所以我尝试添加另一个初始化类.我的所有其他类都是我的AbstractAnnotationConfigDispatcherServletInitializer子类的公共静态内部类,所以我把另一个放在那里作为AbstractSecurityWebApplicationInitializer子类(而不是创建一个单独的.java文件).

WARNING com.caucho.server.webapp.WebApp setConfigException: java.lang.UnsupportedOperationException: unimplemented
at com.caucho.server.webapp.ServletContextImpl.setSessionTrackingModes(ServletContextImpl.java:552)
at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.onStartup(AbstractSecurityWebApplicationInitializer.java:120)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174)
at com.caucho.server.webapp.WebApp.callInitializer(WebApp.java:3471)
at com.caucho.server.webapp.WebApp.callInitializers(WebApp.java:3439)
at com.caucho.server.webapp.WebApp.startImpl(WebApp.java:3661)
at com.caucho.server.webapp.WebApp$StartupTask.run(WebApp.java:5196)
at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
Run Code Online (Sandbox Code Playgroud)

我尝试添加订购无济于事.我的整个配置:

    package com.latencyzero.satdb.web;


//
//  Java Imports
//

import java.util.Properties;
import java.util.ResourceBundle;

import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import javax.sql.DataSource;

//
//  Library Imports
//


import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.xml.DOMConfigurator;

import org.hibernate.SessionFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

import org.springframework.stereotype.Controller;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

//
//  Project Imports
//


/**
    There are still some things that get configured in the container. This app
    was developed using Resin. Things configured in resin's XML config for this
    app include the data source, error page, key store password for Apple
    Push Notifications (which should move to the DB).
*/

public
class
WebappInitializer
    extends
        org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
{
    @Override
    protected
    Class<?>[]
    getRootConfigClasses()
    {
        Class<?>[] classes = { AppConfig.class, SecurityConfig.class };
        return classes;
    }

    @Override
    protected
    Class<?>[]
    getServletConfigClasses()
    {
        Class<?>[] classes = { WebConfig.class };
        return classes;
    }

    @Override
    protected
    java.lang.String[]
    getServletMappings()
    {
        String[] mappings = { "/" };
        return mappings;
    }

    @Override
    protected
    javax.servlet.Filter[]
    getServletFilters()
    {
        return new javax.servlet.Filter[]
        {
            new org.springframework.orm.hibernate3.support.OpenSessionInViewFilter(),
        };
    }

    /** *******************************************************************************************************************
        App context configuration.

        Hibernate config (data access, transactions, data model).
    */

    @Configuration
    @EnableAsync
    @EnableTransactionManagement
    @ComponentScan(basePackages = { "com.mymodelanddao", })
    public
    static
    class
    AppConfig
    {
        @Bean
        public
        org.springframework.jndi.JndiObjectFactoryBean
        dataSource()
        {
            org.springframework.jndi.JndiObjectFactoryBean bean = new org.springframework.jndi.JndiObjectFactoryBean();
            bean.setJndiName("java:comp/env/jdbc/db");
            return bean;
        }

        @Bean
        public
        org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
        sessionFactory()
        {
            DataSource dataSource = (DataSource) dataSource().getObject();

            org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean bean = new org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean();
            bean.setDataSource(dataSource);
            //  TODO: Do we need to scan this, since it's done as part of @ComponentScan?
            bean.setPackagesToScan(new String[] {"com.latencyzero.satdb.model"});

            Properties props = new Properties();
            props.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
            props.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
            props.setProperty("hibernate.jdbc.batch_size", "200");
            props.setProperty("hibernate.show_sql", "false");
            props.setProperty("hibernate.format_sql", "true");
            props.setProperty("hibernate.use_sql_comments", "false");
            props.setProperty("hibernate.generate_statistics", "true");
            bean.setHibernateProperties(props);

            return bean;
        }

        @Bean
        public
        PlatformTransactionManager
        transactionManager()
        {
            SessionFactory sf = sessionFactory().getObject();
            org.springframework.orm.hibernate3.HibernateTransactionManager bean = new org.springframework.orm.hibernate3.HibernateTransactionManager();
            bean.setSessionFactory(sf);
            return bean;
        }

        private static  Logger              sLogger                     =   Logger.getLogger(AppConfig.class);
    }

    /** *******************************************************************************************************************
        Web context configuration.
    */

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackageClasses = { com.mycontrollerclasses })
    public
    static
    class
    WebConfig
        extends
            org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
    {
        @Bean
        public
        InternalResourceViewResolver
        getInternalResourceViewResolver()
        {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/jsp/");
            resolver.setSuffix(".jsp");
            return resolver;
        }

        @Bean
        public
        org.springframework.web.multipart.commons.CommonsMultipartResolver
        multipartResolver()
        {
            return new org.springframework.web.multipart.commons.CommonsMultipartResolver();
        }

        @Override
        public
        void
        addResourceHandlers(ResourceHandlerRegistry inRegistry)
        {
            inRegistry.addResourceHandler("/assets/**").addResourceLocations("/assets/").setCachePeriod(31556926);
            inRegistry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926);
            inRegistry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
        }

        private static  Logger              sLogger                     =   Logger.getLogger(WebConfig.class);
    }

    /** *******************************************************************************************************************
        Security configuration.
    */

    @Configuration
    @EnableWebMvcSecurity
    public
    static
    class
    SecurityConfig
        extends
            org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
    {
        @Autowired
        public
        void
        configureGlobal(AuthenticationManagerBuilder inAuth)
            throws
                Exception
        {
            sLogger.warn("configureGlobal =================================================");
            inAuth
                .inMemoryAuthentication()
                .withUser("user")
                .password("password")
                .roles("USER");
        }

        private static  Logger              sLogger                     =   Logger.getLogger(SecurityConfig.class);
    }

    public
    static
    class
    SecurityWebApplicationInitializer
        extends
            org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

bla*_*lle 1

根据https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#abstractsecuritywebapplicationinitializer-with-spring-mvc,您必须引入第二个WebApplicationInitializer,通常源自AbstractSecurityWebApplicationInitializer

第二个 WebApplicationInitializer 将注册 springFilterChain 属性