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

我不是一个真正的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 } } 

提前致谢。

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

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

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

 servletContext.addFilter(String filterName, java.lang.Class filterClass) 

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

更新

根据更新的信息,我仍然认为该问题与上面提到的WebLogic错误有关。 使用SpringBootServletInitializer时,filter将添加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; } 

然后,您需要确保使用注册filter

 servletContext.addFilter(String filterName, java.lang.Class 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 dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC); registration.addMappingForUrlPatterns(dispatcherTypes, true, "/*"); } } 

DelegatingFilterProxy将查找名为“springSecurityFilterChain”的bean,并在每次调用doFilter时委托给它。

我认为你需要在filter链中添加securityContextPersistenceFilter

  

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

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

为了记录,也许有点晚了,我最近遇到了同样的问题(以及其他)并使用Spring MVC(4.1.1.RELEASE)获得了Spring Security(4.0.0.RELEASE)(不是Spring Boot,因此不使用FilterRegistrationBean as sugested above)在Weblogic 12.1.3上工作。 感谢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 dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC); registration.addMappingForUrlPatterns(dispatcherTypes, true, "/*"); 

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

  springSecurityFilterChain  org.springframework.web.filter.DelegatingFilterProxy    springSecurityFilterChain /*