Reputation: 33544
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
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