Spring Security/CXF 抛出 AuthenticationCredentialsNotFoundException:在 SecurityContext 中找不到身份验证对象
Spring Security/CXF throws AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
我在 REST 服务器平台上工作,该平台由以下组成:
- Spring (v5.1) 使用 Java 配置
- Spring 安全性 (v5.1)
- CXF (v3.3)
- 杰克逊 (v2.9)
到目前为止的完整代码位于 https://github.com/TheChrisPratt/vytamin
但我 运行 遇到了问题。当我提交请求时,它会抛出 org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
我的安全配置基本上是:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationProvider authenticationProvider;
@Bean
@Override
public AuthenticationManager authenticationManagerBean () throws Exception {
return super.authenticationManagerBean();
} //authenticationManagerBean
@Bean
public PasswordEncoder passwordEncoder () {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
} //passwordEncoder
@Override
public void configure (AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
PasswordEncoder encoder = passwordEncoder();
auth.authenticationProvider(authenticationProvider)
.inMemoryAuthentication().withUser("bob").password(encoder.encode("{noop}bobpassword")).roles("USER")
.and().withUser("fred").password(encoder.encode("{noop}fredpassword")).roles("ADMIN","USER");
} //configure
@Override
protected void configure (HttpSecurity http) throws Exception {
log.trace("--==<<(( Configuring HTTP Security ))>>==-----");
http.authorizeRequests().anyRequest().authenticated()
.and().httpBasic()
.and().csrf().disable();
} //configure
} //*SecurityConfig
示例控制器如下所示:
@Path("/course")
@Produces(APPLICATION_JSON)
@Controller("courseResource")
public class CourseResource {
@Autowired
private CourseService courseService;
@GET
@Path("/{courseId}")
@Secured("ROLE_USER")
public Course getCourse (@PathParam("courseId") long courseId) {
return courseService.getById(courseId);
} //getCourse
} //*CourseResource
问题出在@Secured 注释上。在可以对请求进行身份验证之前调用该方法。它希望用户通过身份验证,因此不会通过并抛出异常。
去掉@Secured注解,修改HTTP配置方法如下:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/course/**").hasRole("USER")
.and().csrf().disable();
}
原来我缺少 ExceptionMapper
来映射 AuthenticationException
。一旦我将该异常映射到 401 Unauthorized 响应,它就会开始正确响应请求。
我在 REST 服务器平台上工作,该平台由以下组成:
- Spring (v5.1) 使用 Java 配置
- Spring 安全性 (v5.1)
- CXF (v3.3)
- 杰克逊 (v2.9)
到目前为止的完整代码位于 https://github.com/TheChrisPratt/vytamin
但我 运行 遇到了问题。当我提交请求时,它会抛出 org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
我的安全配置基本上是:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationProvider authenticationProvider;
@Bean
@Override
public AuthenticationManager authenticationManagerBean () throws Exception {
return super.authenticationManagerBean();
} //authenticationManagerBean
@Bean
public PasswordEncoder passwordEncoder () {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
} //passwordEncoder
@Override
public void configure (AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
PasswordEncoder encoder = passwordEncoder();
auth.authenticationProvider(authenticationProvider)
.inMemoryAuthentication().withUser("bob").password(encoder.encode("{noop}bobpassword")).roles("USER")
.and().withUser("fred").password(encoder.encode("{noop}fredpassword")).roles("ADMIN","USER");
} //configure
@Override
protected void configure (HttpSecurity http) throws Exception {
log.trace("--==<<(( Configuring HTTP Security ))>>==-----");
http.authorizeRequests().anyRequest().authenticated()
.and().httpBasic()
.and().csrf().disable();
} //configure
} //*SecurityConfig
示例控制器如下所示:
@Path("/course")
@Produces(APPLICATION_JSON)
@Controller("courseResource")
public class CourseResource {
@Autowired
private CourseService courseService;
@GET
@Path("/{courseId}")
@Secured("ROLE_USER")
public Course getCourse (@PathParam("courseId") long courseId) {
return courseService.getById(courseId);
} //getCourse
} //*CourseResource
问题出在@Secured 注释上。在可以对请求进行身份验证之前调用该方法。它希望用户通过身份验证,因此不会通过并抛出异常。
去掉@Secured注解,修改HTTP配置方法如下:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/course/**").hasRole("USER")
.and().csrf().disable();
}
原来我缺少 ExceptionMapper
来映射 AuthenticationException
。一旦我将该异常映射到 401 Unauthorized 响应,它就会开始正确响应请求。