java - AbstractSecurityWebApplicationInitializer 与 AbstractAnnotationConfigDispatcherServletInitializer

标签 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 节,其中说下一步是向 WAR 注册 springSecurityFilterChain,然后继续说如何在 Servlet 3+ 环境中,我需要子类化 AbstractSecurityWebApplicationInitializer。但我已经继承了 AbstractAnnotationConfigDispatcherServletInitializer。我应该每个都有一个吗? AbstractSecurityWebApplicationInitializer JavaDoc 中有一些关于排序的讨论,暗示我应该有多个初始化程序类。

在所有这些中,它还说要将 WebSecurityConfigurerAdapter 子类添加到 getRootConfigClasses() (尽管该示例没有显示其他 Spring 入门文档让您创建的“AppConfig”;此外,仅此还不够).

所以我尝试添加另一个初始化程序类。我的所有其他类都是我的 AbstractAnnotationConfigDispatcherServletInitializer 子类的公共(public)静态内部类,所以我在其中放了另一个类作为 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)

我尝试添加排序但无济于事。我的整个配置:

    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
    {
    }
}

最佳答案

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

第二个 WebApplicationInitializer 将注册属性 springFilterChain

关于java - AbstractSecurityWebApplicationInitializer 与 AbstractAnnotationConfigDispatcherServletInitializer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22447603/

相关文章:

java - Javascript和Java进行相同的验证

java - Gradle:MessageIOException:无法将消息 [EndOfStream] 写入 127.0.0.1(防火墙)?

javascript - 未捕获的 IndexSizeError : ChartJS

java - 如何使用 XML 从站点生成 HTML

java - 使用 SBT 构建工具在 Java 中编译 Protobufs 时出现编译错误

java - 从 .properties 文件加载消息时出错

java - 带有 ResponseEntity 的 HttpStatus 和 pdf

java - 将restful ajax请求映射到spring

spring - 使用 RabbitMQ stomp 适配器跨不同服务器中的订阅中继消息

java - EntityManagerFactory 和 ApplicationContext 的使用