I have a rest controller that requires the user to be authenticated. But when the test is run the response is always 401. I am using the "WithSecurityContext" annotation, but it does not work.
Annotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
@WithSecurityContext(factory = WithOAuth2AuthenticationSecurityContextFactory.class)
public @interface WithOAuth2Authentication {
String clientId() default "temporal";
String username() default "username";
String[] scopes() default { "read", "write", "trust" };
}
Class implementing annotation
public class WithOAuth2AuthenticationSecurityContextFactory implements WithSecurityContextFactory<WithOAuth2Authentication> {
@Override
public SecurityContext createSecurityContext(WithOAuth2Authentication annotation) {
Set<String> scopes = new HashSet<>();
Collections.addAll(scopes, annotation.scopes());
OAuth2Request oAuth2Request = new OAuth2Request(null, annotation.clientId(), null, true, scopes, null, null, null, null);
Authentication auth2Authentication = new OAuth2Authentication(oAuth2Request, new TestingAuthenticationToken(annotation.username(), null, "read"));
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(auth2Authentication);
return context;
}
}
Unit test
@Before
public void setup() {
this.mapper = new ObjectMapper();
RestDocumentationResultHandler document =
document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()));
this.mock = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.apply(SecurityMockMvcConfigurers.springSecurity())
.alwaysDo(document)
.build();
}
@Test
@WithOAuth2Authentication
public void create() throws Exception {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Accept-Language", "en");
httpHeaders.add("Content-Type", "application/json");
httpHeaders.add("Accept", "application/json");
String JSON = this.mapper.writeValueAsString(new Register.Project());
this.mock.perform(post("/project/create")
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.headers(httpHeaders)
.content(JSON))
.andDo(print())
.andExpect(status().isOk());
}
The result of the test
MockHttpServletResponse:
Status = 401
Error message = null
Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate, no-store], Pragma=[no-cache, no-cache], Expires=[0], X-Frame-Options=[DENY], WWW-Authenticate=[Bearer realm="oauth2-resource", error="unauthorized", error_description="Full authentication is required to access this resource"], Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
Forwarded URL = null
Redirected URL = null
Cookies = []