7

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 everything works fine when the application runs in Tomcat on my local machine and on our testing server. However, as soon as the application is deployed to Weblogic it's as if there is no security at all with all routes accessible. Login and logout routes are non-existent as well.

That being said. Everything else appears to work fine, just without any security at all.

I don't have access to Weblogic as the client is the one deploying the code but they have told us that it's running on 12c. What can I do to fix or troubleshoot this?

Here's the relevant config from my 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
    }

}

Thanks in advance.

Jon Hester
  • 189
  • 1
  • 1
  • 11

4 Answers4

3

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.

Rob Winch
  • 21,440
  • 2
  • 59
  • 76
  • Maybe I'm missing something, but I'm not using AbstractSecurityWebApplicationInitializer anywhere. Not directly anyway. I'm not sure that updating is going to be an option so I'll probably need to fix it myself. – Jon Hester Apr 02 '15 at 17:04
  • When you verify it working in Tomcat, are you deploying it as a war? – Rob Winch Apr 02 '15 at 20:14
  • Yes, I'm deploying it as a war to Tomcat and it works perfectly as is. When deployed to Weblogic, everything works as expected except nothing is secured and the login and logout routes do not work. – Jon Hester Apr 03 '15 at 02:17
  • How did you add springSecurityFilterChain? Spring Boot will automatically map springSecurityFilterChain as a Filter when using an embedded container (i.e. when using an executable jar or an executable war). However, there are extra steps that are necessary when deploying as a war. Did you use a web.xml to map it? – Rob Winch Apr 03 '15 at 14:22
  • I did not add springSecurityFilterChain anywhere. No. The only security related code I have is in my Application.java config file. The relevant contents are in my code block. FWIW, I am using Spring Boot. – Jon Hester Apr 03 '15 at 14:53
  • My outer class for Application.java looks like `public class Application extends SpringBootServletInitializer` – Jon Hester Apr 03 '15 at 15:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74448/discussion-between-jetshred-and-rob-winch). – Jon Hester Apr 03 '15 at 19:56
  • Still didn't work, but I'm not so sure that it's not a separate issue on the client's end, so I'm marking this as the correct answer in hopes that it may help someone else. – Jon Hester Apr 08 '15 at 19:00
  • @JetShred Feel free to open another question and mention me via SO or twitter at rob_winch if SO prevents you from mentioning me and I can take a look at that too – Rob Winch Apr 08 '15 at 19:13
  • @RobWinch , I ran into similar problem and your answer looked very close so far. I implemented your suggestion, but still facing the issue. Can you please look into this question, https://stackoverflow.com/questions/72578781/soap-web-service-is-sending-response-even-when-the-request-does-not-have-okta-to – M S Kulkarni Jun 20 '22 at 17:00
  • @JonHester, did you find any alternative to this problem. – M S Kulkarni Jun 21 '22 at 02:20
  • I have also encountered the same issue. Weblogic is returning error 500 instead of 401 (which is the correct response and what I am getting on my local machine) because my implementation of AuthenticationEntryPoint is not running. Could someone please provide assistance in resolving this? – Lubco Jun 06 '23 at 07:50
1

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.
Mourad Zouabi
  • 2,187
  • 2
  • 15
  • 20
  • Added, but I'm still getting the same issue. – Jon Hester Apr 01 '15 at 18:14
  • Since the application uses Spring Boot all of the filters are created using Java Configuration. That means the securityContextPersistenceFilter XML definition is not necessary. – Rob Winch Apr 02 '15 at 16:22
0

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, "/*");
s.ijpma
  • 930
  • 1
  • 11
  • 23
0

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>
Kevin Hooke
  • 2,583
  • 2
  • 19
  • 33