Moazzam
Moazzam

Reputation: 429

How to pass authentication in spring test case

I am using spring boot 1.5.6 with OAuth 2.0. The problem is that when I run below test case, I get Null pointer exception on below line for authentication object.

 System.out.println(authentication.getName());

Test Class

@RunWith(SpringRunner.class)
@SpringBootTest(classes = WebApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource( locations = "classpath:test-application.properties")
public class ProfileControllerTest {

......
......

     @Before
      public void setup() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
        ...........
        .........
      }

      @Test
      public void profileTest() throws Exception {
        String userId = "12345678";

        mockMvc.perform(get("user/" + userId + "/profile"))
        .andExpect(status().isOk())
          .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8));
      }
}

Rest Controller

  @RequestMapping(value = "user/{userId}/profile",
      method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<Map<String, Object>> getProfile(
      @PathVariable(value = "userId", required = true) String userId,
      HttpServletRequest request, Authentication authentication) {
      System.out.println(authentication.getName());
    }

Security Configuration

@Configuration
@EnableOAuth2Sso
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {

  private static final String OAUTH_COOKIE = "OAUTH-ACCESS-TOKEN";

  private UserService userService;
  private OAuth2TokenAuthenticationFilter ssoFilter;
  private JwtAccessTokenConverter accessTokenConverter;

  /**
   * WebAppSecurity overloaded constructor.
   */
  public WebAppSecurityConfig(UserService userService,
      OAuth2TokenAuthenticationFilter ssoFilter,
      JwtAccessTokenConverter accessTokenConverter) {
    this.userService = userService;
    this.ssoFilter = ssoFilter;
    this.accessTokenConverter = accessTokenConverter;
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.anonymous()
        .disable()
        .authorizeRequests()
        .antMatchers("/logout-success")
        .permitAll()
        .anyRequest()
        .authenticated()
        .and()
        .csrf()
        .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
        .and()
        .addFilterAfter(ssoFilter,
            AbstractPreAuthenticatedProcessingFilter.class).logout()
        .logoutUrl("/logout").logoutSuccessUrl("/logout-success").permitAll()
        .deleteCookies(OAUTH_COOKIE);
  }

  @Autowired
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService());
    configure((DefaultAccessTokenConverter) accessTokenConverter
        .getAccessTokenConverter());
  }

  protected void configure(DefaultAccessTokenConverter accessTokenConverter) {
    DefaultUserAuthenticationConverter userTokenConverter =
        new DefaultUserAuthenticationConverter();
    userTokenConverter.setUserDetailsService(userDetailsService());
    accessTokenConverter.setUserTokenConverter(userTokenConverter);
  }

  @Override
  protected UserDetailsService userDetailsService() {
    return userService;
  }

How to pass Authentication object in above test case?

Upvotes: 2

Views: 1140

Answers (1)

glytching
glytching

Reputation: 47895

You can use the @WithMockUser annotation on your test.

For example:

  @Test
  @WithMockUser(username = "admin", roles = { "ADMIN" }) 
  public void profileTest() throws Exception {
    String userId = "12345678";

    mockMvc.perform(get("user/" + userId + "/profile"))
    .andExpect(status().isOk())
      .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8));
  }

Assuming you have spring-security configured and enabled for the "user/" + userId + "/profile" endpoint then System.out.println(authentication.getName()); in your controller will print: admin.

More details in the Spring Securty docs.

Upvotes: 1

Related Questions