JSON Web Tokens

JSON Web Tokens With Spring Cloud Microservices

Thomas Kendall Java, JavaScript, Microservices, Security 3 Comments

At Keyhole, we have published several blogs about Microservices. We’ve talked about architectural patterns used in a Microservices environment such as service discovery and circuit breaker. We’ve even posted blogs on platforms and tools, such as the recent blog on Service Fabric.

One important piece of the architecture that we have glossed over is the security around Microservices. Specifically, authentication and authorization patterns.

There are several options when considering auth in Microservices, but this blog will specifically focus on using JSON Web Tokens.

JSON Web Tokens

Essentially, A JSON Web Token (JWT) is a self-contained authentication token that can contain information such as a user identifier, roles and permissions of a user, and anything else you might want to store in it. It can be easily read and parsed by anyone and can verified as authentic with a secret key. For a brief introduction to JSON Web Tokens, check out this page.

One advantage of using JSON Web Tokens with Microservices is that we can set it up so that it already contains any authorities that the user has. This means that each service does not need to reach out to our authorization service in order to authorize the user.

Another advantage that JWTs have is that they are serializable and small enough to fit inside a request header.

How It Works

The workflow is fairly simple. The first request is a POST to an unprotected authentication endpoint with a username and password.

On successful authentication, the response contains a JWT. All further requests come with an HTTP header that contains this JWT token in the form of Authorization: xxxxx.yyyyy.zzzzz.

Any service-to-service requests will pass this header along so that any of the services can apply authorization along the way.

Now, To The Code!

The first thing we need to do is figure out how to generate these JWTs. Luckily, we’re not the first to try this and there are several libraries to choose from.

I chose Java JWTHere is my implementation:

public class JsonWebTokenUtility {

	private SignatureAlgorithm signatureAlgorithm;
	private Key secretKey;

	public JsonWebTokenUtility() {

		// For simplicity, we are storing a static key here.
		// Ideally, in a microservices environment, this key would kept on a
		// config server.
		signatureAlgorithm = SignatureAlgorithm.HS512;
		String encodedKey = "L7A/6zARSkK1j7Vd5SDD9pSSqZlqF7mAhiOgRbgv9Smce6tf4cJnvKOjtKPxNNnWQj+2lQEScm3XIUjhW+YVZg==";
		secretKey = deserializeKey(encodedKey);

	public String createJsonWebToken(AuthTokenDetailsDTO authTokenDetailsDTO) {
		String token = Jwts.builder().setSubject(authTokenDetailsDTO.userId).claim("email", authTokenDetailsDTO.email)
				.claim("roles", authTokenDetailsDTO.roleNames).setExpiration(authTokenDetailsDTO.expirationDate)
				.signWith(getSignatureAlgorithm(), getSecretKey()).compact();
		return token;

	private Key deserializeKey(String encodedKey) {
		byte[] decodedKey = Base64.getDecoder().decode(encodedKey);
		Key key = new SecretKeySpec(decodedKey, getSignatureAlgorithm().getJcaName());
		return key;

	private Key getSecretKey() {
		return secretKey;

	public SignatureAlgorithm getSignatureAlgorithm() {
		return signatureAlgorithm;

	public AuthTokenDetailsDTO parseAndValidate(String token) {
		AuthTokenDetailsDTO authTokenDetailsDTO = null;
		try {
			Claims claims = Jwts.parser().setSigningKey(getSecretKey()).parseClaimsJws(token).getBody();
			String userId = claims.getSubject();
			String email = (String) claims.get("email");
			List roleNames = (List) claims.get("roles");
			Date expirationDate = claims.getExpiration();

			authTokenDetailsDTO = new AuthTokenDetailsDTO();
			authTokenDetailsDTO.userId = userId;
			authTokenDetailsDTO.email = email;
			authTokenDetailsDTO.roleNames = roleNames;
			authTokenDetailsDTO.expirationDate = expirationDate;
		} catch (JwtException ex) {
		return authTokenDetailsDTO;

	private String serializeKey(Key key) {
		String encodedKey = Base64.getEncoder().encodeToString(key.getEncoded());
		return encodedKey;


Now that we have this utility class, we need to set up Spring Security in each of our Microservices.

For this, we will need a custom authentication filter that will read the request header if it is present. There is an authentication filter in Spring that already does this called the RequestHeaderAuthenticationFilter that we can extend.

public class JsonWebTokenAuthenticationFilter extends RequestHeaderAuthenticationFilter {

	public JsonWebTokenAuthenticationFilter() {
		// Don't throw exceptions if the header is missing

		// This is the request header it will look for

	public void setAuthenticationManager(AuthenticationManager authenticationManager) {

At this point, the header has been converted into a Spring Authentication object in the form of a PreAuthenticatedAuthenticationToken.

We now need an authentication provider that will read this token, authenticate it, and convert it to our own custom Authentication object.

public class JsonWebTokenAuthenticationProvider implements AuthenticationProvider {

	private JsonWebTokenUtility tokenService = new JsonWebTokenUtility();

	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		Authentication authenticatedUser = null;
		// Only process the PreAuthenticatedAuthenticationToken
		if (authentication.getClass().isAssignableFrom(PreAuthenticatedAuthenticationToken.class)
				&& authentication.getPrincipal() != null) {
			String tokenHeader = (String) authentication.getPrincipal();
			UserDetails userDetails = parseToken(tokenHeader);
			if (userDetails != null) {
				authenticatedUser = new JsonWebTokenAuthentication(userDetails, tokenHeader);
		} else {
			// It is already a JsonWebTokenAuthentication
			authenticatedUser = authentication;
		return authenticatedUser;

	private UserDetails parseToken(String tokenHeader) {

		UserDetails principal = null;
		AuthTokenDetailsDTO authTokenDetails = tokenService.parseAndValidate(tokenHeader);

		if (authTokenDetails != null) {
			List<GrantedAuthority> authorities = authTokenDetails.roleNames.stream()
					.map(roleName -> new SimpleGrantedAuthority(roleName)).collect(Collectors.toList());
			principal = new User(authTokenDetails.email, "", authorities);

		return principal;

	public boolean supports(Class<?> authentication) {
		return authentication.isAssignableFrom(PreAuthenticatedAuthenticationToken.class)
				|| authentication.isAssignableFrom(JsonWebTokenAuthentication.class);


With these components in place, we now have standard Spring Security wired up to use JWTs. When making service-to-service calls, we will need to pass the JWT along.

I used a Feign client, passing the JWT as a parameter.

public interface UserManagementServiceAPI {

	@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
	AuthTokenDTO authenticateUser(@RequestBody AuthenticationDTO authenticationDTO);

	@RequestMapping(method = RequestMethod.POST, value = "/roles")
	RoleDTO createRole(@RequestHeader("Authorization") String authorizationToken, @RequestBody RoleDTO roleDTO);

	@RequestMapping(method = RequestMethod.POST, value = "/users")
	UserDTO createUser(@RequestHeader("Authorization") String authorizationToken, @RequestBody UserDTO userDTO);

	@RequestMapping(method = RequestMethod.DELETE, value = "/roles/{id}")
	void deleteRole(@RequestHeader("Authorization") String authorizationToken, @PathVariable("id") int id);

	@RequestMapping(method = RequestMethod.DELETE, value = "/users/{id}")
	void deleteUser(@RequestHeader("Authorization") String authorizationToken, @PathVariable("id") int id);

	@RequestMapping(method = RequestMethod.GET, value = "/roles")
	Collection<RoleDTO> findAllRoles(@RequestHeader("Authorization") String authorizationToken);

	@RequestMapping(method = RequestMethod.GET, value = "/users")
	Collection<UserDTO> findAllUsers(@RequestHeader("Authorization") String authorizationToken);

	@RequestMapping(method = RequestMethod.GET, value = "/roles/{id}", produces = "application/json", consumes = "application/json")
	RoleDTO findRoleById(@RequestHeader("Authorization") String authorizationToken, @PathVariable("id") int id);

	@RequestMapping(method = RequestMethod.GET, value = "/users/{id}", produces = "application/json", consumes = "application/json")
	UserDTO findUserById(@RequestHeader("Authorization") String authorizationToken, @PathVariable("id") int id);

	@RequestMapping(method = RequestMethod.GET, value = "/users/{id}/roles")
	Collection<RoleDTO> findUserRoles(@RequestHeader("Authorization") String authorizationToken,
			@PathVariable("id") int id);

	@RequestMapping(method = RequestMethod.PUT, value = "/roles/{id}")
	void updateRole(@RequestHeader("Authorization") String authorizationToken, @PathVariable("id") int id,
			@RequestBody RoleDTO roleDTO);

	@RequestMapping(method = RequestMethod.PUT, value = "/users/{id}")
	void updateUser(@RequestHeader("Authorization") String authorizationToken, @PathVariable("id") int id,
			@RequestBody UserDTO userDTO);

In order to pass the JWT along, I just grabbed it from Spring Security in my controller like this:

private String getAuthorizationToken() {
	String token = null;
	Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
	if (authentication != null && authentication.getClass().isAssignableFrom(JsonWebTokenAuthentication.class)) {
		JsonWebTokenAuthentication jwtAuthentication = (JsonWebTokenAuthentication) authentication;
		token = jwtAuthentication.getJsonWebToken();
	return token;

As you can tell, JWTs fit nicely in a distributed Microservices environment and provide plenty of versatility. When designing the security architecture for your next Microservices project, consider JSON Web Tokens.

About the Author
Thomas Kendall

Thomas Kendall

Thomas is a full-stack software architect and consultant with Keyhole Software. He brings 10+ years of experience to the table working with a variety of technology stacks including Java, .NET and AngularJS. His latest endeavors (when not destroying the competition in the Keyhole fantasy football league) include diving into Microservices and toying around with web sockets.

Share this Post

Comments 3

  1. Zach Gardner

    Thomas, thanks so much for posting this! I’ve been researching using JWT for my own microservices implementation, and it’s really helpful to see all of this in one place.

    Curious, is it necessary for the controller to obtain the auth token?
    I’m assuming that it’s getting it from the security context so it can check if the roles present match the requirements of the controller.
    I was hoping that there was some way I could defined as part of the controller method via an annotation which roles are required for its security, then having Spring Security take care of that behind the scenes.

    Also, do you have a link to a github repo where this code is working?

    1. Thomas Kendall Post
      Thomas Kendall

      You’re right. If you need to check authorization in the controller, you can use all of the standard Spring Security stuff like @PreAuthorize. You won’t need to manually get the auth token. The only reason I was getting the auth token in the controller was so that I could pass it to the Feign clients to pass to other service calls. There are other ways to configure Feign clients to automatically do this as well.

    2. Thomas Kendall Post

Leave a Reply