我遇到SecurityContextHolder.getContext().getAuthentication()
的问题,这是空的。我已经尝试了许多与注释和示例的组合。 (来自网站的代码在我的应用程序中不起作用,不知道为什么)。
所以现在我得到org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
。如果您查看sources,您会发现getAuthentification
被委托给SecurityContextHolderStrategy
哪个线程本地字段并在SecurityContextHolder
初始化期间填充。任何人都知道什么时候春天安全应该"填充"它与认证? (在servlet过滤器中,在方法调用之前等)
已更新
安全配置是:
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\"}";
}
}
应用程序初始化程序
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
包含用于sprng数据休息的数据源,entityManager和transactionManager配置的一些代码。
请求/rest/allow
url导致异常org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
注意
表单授权配置可能不正确,我尝试用基本身份验证替换它,但无论如何我应该得到未经授权的响应而不是异常。
版本
Spring为4.0.5.RELEASE
,Spring安全性为4.0.2.RELEASE
。
答案 0 :(得分:2)
修复弹簧安全性的解决方案非常简单,只需添加:
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {}
并将SecurityConfiguration.class
移至getRootConfigClasses()
方法。
一切正常! :)