Presta atención ya que en esta crónica encontrarás la contestación que buscas.
Solución:
Creo que resolví el problema (y espero no estar haciendo una mala práctica o creando una vulnerabilidad de seguridad en mi backend).
Seguí el consejo de @ punkrocker27ka y miré esta respuesta. En él dicen que están generando un token Oauth manualmente para las pruebas, así que decidí hacer lo mismo con mi token JWT.
Así que actualicé mi clase que genera los tokens JWT y los valida para que sean así:
public class TokenAuthenticationService
static final long EXPIRATIONTIME = 864_000_000; // 10 days
static final String SECRET = "ThisIsASecret";
static final String TOKEN_PREFIX = "Bearer";
static final String HEADER_STRING = "Authorization";
public static void addAuthentication(HttpServletResponse res, String username)
String jwt = createToken(username);
res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + jwt);
public static Authentication getAuthentication(HttpServletRequest request)
String token = request.getHeader(HEADER_STRING);
if (token != null)
// parse the token.
String user = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
return user != null ?
new UsernamePasswordAuthenticationToken(user, null, Collections.emptyList()) :
null;
return null;
public static String createToken(String username)
String jwt = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
return jwt;
Y luego creé una nueva prueba para ello:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class TokenAuthenticationServiceTest
@Autowired
private MockMvc mvc;
@Test
public void shouldNotAllowAccessToUnauthenticatedUsers() throws Exception
mvc.perform(MockMvcRequestBuilders.get("/test")).andExpect(status().isForbidden());
@Test
public void shouldGenerateAuthToken() throws Exception
String token = TokenAuthenticationService.createToken("john");
assertNotNull(token);
mvc.perform(MockMvcRequestBuilders.get("/test").header("Authorization", token)).andExpect(status().isOk());
Luego ejecuté las pruebas y pasaron, por lo que el token fue aceptado sin la necesidad de @WithMockUser
anotación. Agregaré esto a mis otras clases de pruebas.
PD: el punto final de la prueba está por debajo.
/**
* This controller is used only for testing purposes.
* Especially to check if the JWT authentication is ok.
*/
@RestController
public class TestController
@RequestMapping(path = "/test", method = RequestMethod.GET)
public String testEndpoint()
return "Hello World!";
Una cosa que debe tener en cuenta al probar con este método createToken () es que sus pruebas no pueden probar para un usuario inexistente.
Esto se debe a que createToken () solo crea un token JWT basado en el string pones en él.
Si desea asegurarse de que los usuarios inexistentes no puedan obtener acceso, le recomiendo hacer que su método createToken () sea privado y, en su lugar, use solicitudes para obtener el token, como este:
@Test
public void existentUserCanGetTokenAndAuthentication() throws Exception
String username = "existentuser";
String password = "password";
String body = ""username":"" + username + "", "password":"
+ password + """;
MvcResult result = mvc.perform(MockMvcRequestBuilders.post("/v2/token")
.content(body))
.andExpect(status().isOk()).andReturn();
String response = result.getResponse().getContentAsString();
response = response.replace(""access_token": "", "");
String token = response.replace(""", "");
mvc.perform(MockMvcRequestBuilders.get("/test")
.header("Authorization", "Bearer " + token))
.andExpect(status().isOk());
De manera similar, puede mostrar que un usuario inexistente no podrá obtener este resultado:
@Test
public void nonexistentUserCannotGetToken() throws Exception
String username = "nonexistentuser";
String password = "password";
String body = ""username":"" + username + "", "password":"
+ password + """;
mvc.perform(MockMvcRequestBuilders.post("/v2/token")
.content(body))
.andExpect(status().isForbidden()).andReturn();
Ten en cuenta comunicar esta crónica si si solucionó tu problema.