Spring Security/CXF 抛出 AuthenticationCredentialsNotFoundException:在 SecurityContext 中找不到身份验证对象

Spring Security/CXF throws AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

我在 REST 服务器平台上工作,该平台由以下组成:

到目前为止的完整代码位于 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 响应,它就会开始正确响应请求。