0

Using the new Spring-Security-Web starting with 6.0.0, I wanted to know how to validate a Bearer JWT using a RS256 public key and set the "Authentication" in the Spring Security Servlet Context.

Currently I've written a custom JwtTokenFilter which is added to a SecurityFilterChain. It reads the public key using the X509EncodedKeySpec

jwtPublicKey points to the .pub file

Resource resource = new ClassPathResource(jwtPublicKey);
FileInputStream is = new FileInputStream(resource.getFile());
byte[] bytes = is.readAllBytes();
is.close();

String temp = new String(bytes);
String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
publicKeyPEM = publicKeyPEM.replace("\n", "");

// Decode the contents of the file from Base64
base64EncodedKeyBytes = java.util.Base64.getDecoder().decode(publicKeyPEM);

// Convert the contents of the file to a RSAPublicKey object
X509EncodedKeySpec spec = new X509EncodedKeySpec(base64EncodedKeyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
publicKey = (RSAPublicKey) kf.generatePublic(spec);

*base64EncodedKeyBytes and publicKey are static variables.

How can I now validate a JWT using this public key? I feel like this is all very tedious and I have the feeling there must be a shorter way already included into Spring? (oh lord, please!)

nonNumericalFloat
  • 1,348
  • 2
  • 15
  • 32

1 Answers1

1

You can try something like this:

First, you can add the java-jwt dependency in your pom.xml file

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>4.0.0</version>
</dependency>

Next, you can modify your logic as follows:

@Component
public class JwtTokenVerifier {
 
    // please input your jwt token & public key here
    public static final String jwtToken = "";
    public static final String publicKey = "";
 
    public boolean isTokenValid(String token) {
        try {
            buildJWTVerifier().verify(token.replace("Bearer ", ""));
            // if token is valid no exception will be thrown
            return true;
        } catch (CertificateException e) {
            //if CertificateException comes from buildJWTVerifier()
            e.printStackTrace();
            return false;
        } catch (JWTVerificationException e) {
            // if JWT Token in invalid
            e.printStackTrace();
            return false;
        } catch (Exception e) {
            // If any other exception comes
            e.printStackTrace();
            return false;
        }
    }
 
 
    private JWTVerifier buildJWTVerifier() throws CertificateException {
        var algo = Algorithm.RSA256(getRSAPublicKey(), null);
        return JWT.require(algo).build();
    }
 
    private RSAPublicKey getRSAPublicKey() throws CertificateException {
        var decode = Base64.getDecoder().decode(publicKey);
        var certificate = CertificateFactory.getInstance("X.509")
                .generateCertificate(new ByteArrayInputStream(decode));
        var publicKey = (RSAPublicKey) certificate.getPublicKey();
        return publicKey;
    }
}
inkredusk
  • 919
  • 4
  • 16