Why is Spring Security working in Tomcat but not when deployed to Weblogic?

前端 未结 4 921
野性不改
野性不改 2021-01-03 00:03

I\'m not really a Java developer, but a project for a client has required me to be, so maybe I\'m missing something glaringly obvious.

I\'m using SpringBoot and ever

相关标签:
4条回答
  • 2021-01-03 00:40

    For the record and perhaps a little late, i recently ran into the same issue (amongst others) and got Spring Security (4.0.0.RELEASE) using Spring MVC (4.1.1.RELEASE) (not Spring Boot, so not using the FilterRegistrationBean as sugested above) working on Weblogic 12.1.3. With thanks to Rob Winch for the Filterchain addition (solving the problem of all url's being accessable without security). Implementing the WebApplicationInitializer and overriding the onStart method as follows does the trick:

        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(SecurityConfiguration.class);
    
        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));
    
        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
        dispatcherServlet.register(WebMvcConfiguration.class);
    
        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    
        // Register spring security FilterChain
        FilterRegistration.Dynamic registration = container.addFilter("springSecurityFilterChain", DelegatingFilterProxy.class);
        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC);
        registration.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
    
    0 讨论(0)
  • 2021-01-03 00:43

    It sounds as though you are running into SEC-2465. In short, there is a bug in WebLogic related to adding Filter instances. From the above JIRA:

    Oracle acknowledged it as a bug: 17382048, fixed with patch 16769849. It is reported as being fixed in WLS 12.1.3

    The client should update their WebLogic server to get a fix. Alternatively, you can create your own version of AbstractSecurityWebApplicationInitializer that registers springSecurityFilterChain with the class method:

    servletContext.addFilter(String filterName, java.lang.Class<? extends Filter> filterClass)
    

    Your subclass of AbstractSecurityWebApplicationInitializer would then extend your custom class instead.

    Update

    Based on the updated information, I still contend the issue is related to the WebLogic bug mentioned above. When using SpringBootServletInitializer, the Filters are added with FilterRegistrationBean as an instance rather than a class.

    The easiest option is to update to WebLogic since everything should work as is.

    To workaround the issue, you can disable the registration of Spring Security and any other Filters. You can do this by creating a FilterRegistrationBean like the following:

    @Bean
    public FilterRegistrationBean springSecurityFilterChainRegistrationBean(@Qualifier("springSecurityFilterChain") Filter filter) {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(filter);
        bean.setEnabled(false);
        return bean;
    }
    

    Then you need to ensure the Filter is registered using

    servletContext.addFilter(String filterName, java.lang.Class<? extends Filter> filterClass)
    

    Spring Security can be registered with the above mechanism by implementing WebApplicationInitializer. For example, you can create the following class:

    package demo;
    
    import java.util.EnumSet;
    
    import javax.servlet.FilterRegistration.Dynamic;
    import javax.servlet.*;
    
    import org.springframework.web.WebApplicationInitializer;
    import org.springframework.web.filter.DelegatingFilterProxy;
    
    public class SecurityInitializer implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext context) throws ServletException {
            Dynamic registration =
                    context.addFilter("springSecurityFilterChain", DelegatingFilterProxy.class);
            EnumSet<DispatcherType> dispatcherTypes =
                    EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC);
            registration.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
        }
    }
    

    DelegatingFilterProxy will look up a bean of the name "springSecurityFilterChain" and delegate to it every time doFilter is invoked.

    0 讨论(0)
  • 2021-01-03 00:56

    I think you need to add the securityContextPersistenceFilter in the filter chain

    <bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
    

    I found the following comment in the SecurityContextPersistenceFilter class :

     * This filter will only execute once per request, to resolve servlet container (specifically Weblogic)
     * incompatibilities.
    
    0 讨论(0)
  • 2021-01-03 00:57

    For completeness, if you're deploying to an older version of Weblogic with Servlet spec < 3.0 (e.g. 10.3.6 with 2.5), then you'll need to define the springSecurityFilterChain in your web.xml:

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    0 讨论(0)
提交回复
热议问题