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

302 Views Asked by At

I'm working on a REST server platform that's composed of:

  • Spring (v5.1) Using Java Configuration
  • Spring Security (v5.1)
  • CXF (v3.3)
  • Jackson (v2.9)

The full code so far is at https://github.com/TheChrisPratt/vytamin

But I'm running into a problem. When I submit a request it's throwing org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

My Security Configuration is basically:

@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

And an example controller would look like:

@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
2

There are 2 best solutions below

0
TheChrisPratt On BEST ANSWER

It turns out I was missing an ExceptionMapper to map AuthenticationException's. Once I mapped that exception to a 401 Unauthorized response it started properly responding to the requests.

1
Muizz Mahdy On

The issue is the @Secured annotation. The method is invoked before the request can be authenticated. It expects the user to be authenticated, so it doesn't pass and throws the exception.

Remove the @Secured annotation and edit the HTTP configure method as follows:

 @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
        .httpBasic().and()
        .authorizeRequests()
        .antMatchers(HttpMethod.GET, "/course/**").hasRole("USER")
        .and().csrf().disable();
  }