---
title: "Add JWT Authentication to Your undefined API"
description: undefined
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/java/sparkjava/jwt-backend"
framework: undefined
language: undefined
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your undefined API



## How Zuplo Handles It

Let Zuplo issue short-lived JWTs signed with a JWKS your undefined backend can verify — no long-lived API keys touch your origin.

## undefined Backend Code

```java
import com.auth0.jwk.Jwk;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwk.JwkProviderBuilder;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.RSAKeyProvider;
import spark.Filter;
import spark.Spark;

import java.security.interfaces.RSAPublicKey;
import java.util.concurrent.TimeUnit;

public class JwtAuthExample {

    private static final String ISSUER = "https://my-api-a32f34.zuplo.api/__zuplo/issuer";
    private static final String JWKS_URI = ISSUER + "/.well-known/jwks.json";

    public static void main(String[] args) {
        JwkProvider jwkProvider = new JwkProviderBuilder(JWKS_URI)
                .cached(10, 10, TimeUnit.MINUTES) // up to 10 keys cached for 10 min
                .build();

        Spark.before("/protected", jwtFilter(jwkProvider));

        Spark.get("/protected", (req, res) -> {
            // Access granted to this endpoint
            return "{\"message\": \"Access granted\", \"user\": \"" + req.attribute("user") + "\"}";
        });

        // Other route definitions...
    }

    private static Filter jwtFilter(JwkProvider provider) {
        return (request, response) -> {
            String authHeader = request.headers("Authorization");

            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                halt(401, "{\"error\":\"No token provided\"}");
            }

            try {
                String token = authHeader.replace("Bearer ", "");
                DecodedJWT jwt = JWT.decode(token);
                Jwk jwk = provider.get(jwt.getKeyId());

                RSAKeyProvider keyProvider = new RSAKeyProvider() {
                    @Override
                    public RSAPublicKey getPublicKeyById(String kid) {
                        return (RSAPublicKey) jwk.getPublicKey();
                    }

                    @Override
                    public RSAPublicKey getPrivateKey() {
                        return null;
                    }

                    @Override
                    public String getPrivateKeyId() {
                        return null;
                    }
                };

                DecodedJWT decodedJWT = JWT.require(keyProvider)
                        .withIssuer(ISSUER)
                        .build()
                        .verify(token);

                request.attribute("user", decodedJWT.getSubject());

            } catch (Exception e) {
                halt(401, "{\"error\":\"Invalid token\", \"details\":\"" + e.getMessage() + "\"}");
            }
        };
    }
}
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
