Spring Boot Unit Tests with JWT Token Security

One thing you need to be aware of when testing using this createToken() method is that your tests cannot test for a nonexistent user.
This is because createToken() only makes a JWT token based off of the string you put into it.
If you want to make sure nonexistent users cannot gain access, I recommend making your createToken() method private and instead use requests to gain the token, like this:

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")

    String response = result.getResponse().getContentAsString();
    response = response.replace("{\"access_token\": \"", "");
    String token = response.replace("\"}", "");

        .header("Authorization", "Bearer " + token))

In a similar way, you can show that a nonexistent user will not be able to get this result:

public void nonexistentUserCannotGetToken() throws Exception {
    String username = "nonexistentuser";
    String password = "password";

    String body = "{\"username\":\"" + username + "\", \"password\":\" 
                  + password + "\"}";


I believe that I solved the problem (and I hope I am not doing a bad practice or creating a security vulnerability on my backend).

I followed @punkrocker27ka's advice and looked at this answer. In it they say that they are generating an Oauth token manually for the tests, so I decided to do the same thing for my JWT token.

So I updated my class that generates the JWT tokens and validates them to be like this:

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()
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))

            return user != null ?
                    new UsernamePasswordAuthenticationToken(user, null, Collections.emptyList()) :
        return null;

    public static String createToken(String username) {
        String jwt = Jwts.builder()
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                .signWith(SignatureAlgorithm.HS512, SECRET)

        return jwt;

And then I created a new test for it:

public class TokenAuthenticationServiceTest {

    private MockMvc mvc;

    public void shouldNotAllowAccessToUnauthenticatedUsers() throws Exception {

    public void shouldGenerateAuthToken() throws Exception {
        String token = TokenAuthenticationService.createToken("john");

        mvc.perform(MockMvcRequestBuilders.get("/test").header("Authorization", token)).andExpect(status().isOk());


Then I ran the tests and they passed, so the token was accepted without the need for the @WithMockUser annotation. I will add this to my other tests classes.

PS: The test endpoint is below.

 * This controller is used only for testing purposes.
 * Especially to check if the JWT authentication is ok.
public class TestController {

    @RequestMapping(path = "/test", method = RequestMethod.GET)
    public String testEndpoint() {
        return "Hello World!";