Cherry
Cherry

Reputation: 33544

When SecurityContextHolder.setContext() is invoked?

I have a trouble with SecurityContextHolder.getContext().getAuthentication() which is null. I have tried a lot of combination with annotations and examples. (code from site does not work in my application, do not know why yet).

So for now I get org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext. If you look at sources you spot that getAuthentification is delegated to SecurityContextHolderStrategy which thread local field and populated during SecurityContextHolder initialization. Anybody know when spring security should "populate" it with authentification? (in servlet filter, before method invocation, etc.)

UPDATED

Security configuration is:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableGlobalAuthentication
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
        .antMatchers("/rest/**").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin()
        .loginPage("/login")
        .permitAll()
        .and()
        .logout()
        .permitAll();
  }

  @Override
  protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }
}

RestController

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SecurityChecker {

  @PreAuthorize("isAuthenticated()")
  @RequestMapping("/allow")
  public String allow() {
    return "{\"status\" : \"ok\"}";
  }

  @PreAuthorize("isAnonymous()")
  @RequestMapping("/anonymous")
  public String anonymous() {
    return "{\"status\" : \"anonymous\"}";
  }
}

Application initializer

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[]{AppConfiguration.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class[]{SecurityConfiguration.class};
}

@Override
protected String[] getServletMappings() {
    return new String[]{"/rest/*"};
}

AppConfiguration contains some code for data source, entityManager and transactionManager config for sprng data rest.

Request to /rest/allow url result in exception org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

Note

Form authorization config may be not correct, I tried to replace it with basic auth, but anyway I should get unauthorized response instead fo exception.

Versions

Spring is 4.0.5.RELEASE, spring security is 4.0.2.RELEASE.

Upvotes: 3

Views: 2927

Answers (1)

Cherry
Cherry

Reputation: 33544

The solution for fixing spring security was very simple just add:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {}

and move SecurityConfiguration.class to getRootConfigClasses() method.

And everything works! :)

Upvotes: 2

Related Questions