为什么Spring Security在Tomcat中工作,但在部署到Weblogic时却没有?

时间:2015-04-01 13:50:26

标签: java spring spring-security spring-boot weblogic12c

我不是一个真正的Java开发人员,但是客户的项目要求我这样做,所以也许我错过了一些明显的东西。

我使用SpringBoot,当应用程序在我的本地计算机和测试服务器上的Tomcat中运行时,一切正常。但是,只要将应用程序部署到Weblogic,就好像根本没有安全性可访问所有路由一样。登录和注销路线也不存在。

话虽如此。其他一切看起来都很好,完全没有任何安全性。

我无法访问Weblogic,因为客户端是部署代码的客户端,但他们告诉我们它在12c上运行。我该怎么做才能解决或解决这个问题?

这是我的Application.java中的相关配置:

/**
 * The type Authentication security.
 */
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {

    /**
     * The Users.
     */
    @Autowired
    private Users users;

    /**
     * Init void.
     *
     * @param auth the auth
     * @throws Exception the exception
     */
    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(users).passwordEncoder(new BCryptPasswordEncoder());
    }
}

/**
 * The type Application security.
 */
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    /**
     * Configure void.
     *
     * @param http the http
     * @throws Exception the exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.authorizeRequests()
                .antMatchers("/vendor/*","/public/**/*","/partners/*","/events/*", "/login").permitAll()
                .anyRequest().fullyAuthenticated().and().formLogin().loginPage("/login")
                .and().logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).and()
                .exceptionHandling().accessDeniedPage("/access?error");
        // @formatter:on
    }

}

提前致谢。

4 个答案:

答案 0 :(得分:3)

听起来好像你遇到了SEC-2465。简而言之,WebLogic中存在与添加Filter实例相关的错误。从上面的JIRA:

  

Oracle承认它是一个错误:17382048,修复了补丁16769849。   据报道,已在WLS 12.1.3中修复了

客户端应更新其WebLogic服务器以获取修复程序。或者,您可以创建自己的AbstractSecurityWebApplicationInitializer版本,使用类方法注册springSecurityFilterChain:

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

然后,您的AbstractSecurityWebApplicationInitializer的子类将扩展您的自定义类。

<强>更新

根据更新的信息,我仍然认为该问题与上面提到的WebLogic错误有关。使用SpringBootServletInitializer时,过滤器会添加FilterRegistrationBean作为实例而不是类。

最简单的选择是更新到WebLogic,因为一切都应该按原样运行。

要解决此问题,您可以禁用Spring Security和任何其他过滤器的注册。您可以通过创建如下所示的FilterRegistrationBean来完成此操作:

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

然后,您需要确保使用

注册过滤器
servletContext.addFilter(String filterName, java.lang.Class<? extends Filter> filterClass)

可以通过实施WebApplicationInitializer向上述机制注册Spring Security。例如,您可以创建以下类:

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将查找名为“springSecurityFilterChain”的bean,并在每次调用doFilter时委托给它。

答案 1 :(得分:1)

我认为您需要在过滤器链中添加securityContextPersistenceFilter

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

我在SecurityContextPersistenceFilter类中找到了以下注释:

 * This filter will only execute once per request, to resolve servlet container (specifically Weblogic)
 * incompatibilities.

答案 2 :(得分:0)

对于记录而且可能有点晚了,我最近遇到了同样的问题(以及其他)并使用Spring MVC(4.1.1.RELEASE)获得了Spring Security(4.0.0.RELEASE)(不是Spring Boot,所以在Weblogic 12.1.3上工作时不使用上面提到的FilterRegistrationBean。感谢Rob Winch对Filterchain的补充(解决了所有url在没有安全性的情况下可访问的问题)。 实现WebApplicationInitializer并覆盖onStart方法,如下所示:

    // 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, "/*");

答案 3 :(得分:0)

为了完整起见,如果您使用Servlet规范部署到旧版本的Weblogic&lt; 3.0(例如10.3.6,2.5),那么你需要在web.xml中定义springSecurityFilterChain:

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