Reputation: 4876
I don't want to verify the JWT using the secret key (which I don't have), I only want to decode the JWT and read the payload. Can this be achieved using jsonwebtoken.io:jjwt? It seems like there is a method missing in the API.
Of course, I could split-&-Base64-decode the token myself but it feels like the most basic functionality one would expect from a JWT-library; hence I suspect I am missing something.
Upvotes: 23
Views: 19118
Reputation: 9133
Try to use the JWTParser.parse(token)
of the com.nimbusds:nimbus-jose-jwt:{version}
:
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>9.37.3</version>
</dependency>
import java.text.ParseException;
import java.util.Map;
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTParser;
public class Main {
public static void main(String[] args) throws ParseException {
String token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJZRU9iU1ZKdWZsem9WYW1KX05EbnZUbFA1SVNRVXNaRzRBVUZlWDFGZVFrIn0.eyJleHAiOjE3MDQ0MzAyODksImlhdCI6MTcwNDQyOTk4OSwianRpIjoiMjhlNzE4N2YtM2EwNS00YTQxLWJiODUtYmJiZDg4MDM3OTRkIiwiaXNzIjoiaHR0cDovL25vZGUtMDo4MDgwL3JlYWxtcy9zcG1pYS1yZWFsbSIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI1NTk0OGNmMS04ZTNiLTQ4ZjUtYThkOC1lMGJmMDI2NDRjNjkiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJvc3RvY2siLCJzZXNzaW9uX3N0YXRlIjoiNjgxODIwOGYtZTM5Yy00NjQ3LWEzMjEtMTQ4YWU5MmJhMmE5IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIqIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsImRlZmF1bHQtcm9sZXMtc3BtaWEtcmVhbG0iLCJ1bWFfYXV0aG9yaXphdGlvbiIsIm9zdG9jay1hZG1pbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7Im9zdG9jayI6eyJyb2xlcyI6WyJBRE1JTiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwic2lkIjoiNjgxODIwOGYtZTM5Yy00NjQ3LWEzMjEtMTQ4YWU5MmJhMmE5IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByZWZlcnJlZF91c2VybmFtZSI6ImlsbGFyeS5odWF5bHVwbyJ9.NF0MzYSVkfDTo4YT8wmyibeY-D14C9J1kpCa5EUTRXQbdZX3Wbo053UsqlMMV6NVdG7jjQb1sG3So-nL-H6MLZyg0nmnfsmcnR5j315I6NCqGuJnMXxmbVxqUQViLW1lenJDGkDk2IOr2uJDcdTUR6pSemhnaXKOY47vEJ5dTTlvS73rJ1FQHKEv3kj50SjhgBSzRNuR7Ejghfnnp5kEXSekv40hLFXhE4Som_ZJ8IsYzTOvBMPnbYa5STNgprhcOlvmeiswXDrtyH2udd4qxxURivX7VAVT-Qt8_ozvGyQr7V4u5f4NRq-5i-SVYJtIjqwQOxnUrUMjzF1IDtCqow";
JWT jwt = JWTParser.parse(token);
Map<String, Object> claims = jwt.getJWTClaimsSet().getClaims();
for (String key : claims.keySet()) {
System.out.printf("%s: %s\n", key, claims.get(key));
}
}
}
The nimbus-jose-jwt
is also used by the org.springframework.boot:spring-boot-starter-oauth2-resource-server
:
[INFO] +- org.springframework.boot:spring-boot-starter-oauth2-resource-server:jar:3.2.1:compile
[INFO] | +- org.springframework.security:spring-security-config:jar:6.2.1:compile
[INFO] | +- org.springframework.security:spring-security-core:jar:6.2.1:compile
[INFO] | | \- org.springframework.security:spring-security-crypto:jar:6.2.1:compile
[INFO] | +- org.springframework.security:spring-security-oauth2-resource-server:jar:6.2.1:compile
[INFO] | | +- org.springframework.security:spring-security-oauth2-core:jar:6.2.1:compile
[INFO] | | \- org.springframework.security:spring-security-web:jar:6.2.1:compile
[INFO] | \- org.springframework.security:spring-security-oauth2-jose:jar:6.2.1:compile
[INFO] | \- com.nimbusds:nimbus-jose-jwt:jar:9.24.4:compile
[INFO] | \- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile
BTW, I also tried to use the io.jsonwebtoken
, but it seems that it required to verify the signature of the token. Such as The JWS header references signature algorithm 'RS256' but the compact JWE string is missing the required signature.
Upvotes: 3
Reputation: 31
If you can use another library, it can be done as accepted answer here: How to decode JWT token to get details of Header and Payload using nimbus-jose-jwt?
Repeating the answer here:
dependency:
com.nimbusds:nimbus-jose-jwt:<version>
usage:
/**
* accessToken: the JWT string text.
**/
private String parseJWT(String accessToken) {
try {
var decodedJWT = SignedJWT // or PlainJWT or EncryptedJWT
.parse(accessToken);
var header = decodedJWT.getHeader().toString();
var payload = decodedJWT.getPayload().toString();
} catch (ParseException e) {
throw new Exception("Invalid token!");
}
}
Upvotes: 3
Reputation: 1546
Maybe use the Auth0 library instead?
DecodedJWT jwt = JWT.decode(token);
jwt.getToken();
Dependencies:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>jwks-rsa</artifactId>
<version>0.9.0</version>
</dependency>
Example taken from https://medium.com/trabe/validate-jwt-tokens-using-jwks-in-java-214f7014b5cf
Upvotes: 6
Reputation: 745
Try the following code:
int i = jws.lastIndexOf('.')
String withoutSignature = jws.substring(0, i+1);
Jwt<Header,Claims> untrusted = Jwts.parser().parseClaimsJwt(withoutSignature);
You can 'chop off' the last 'part' after the last period character ('.'), which is the JWS signature.And then read that JWT as a 'normal' JWT (non-JWS).
What you are asking for is to ignore the signature on a valid JWS and read the JWT header and body anyway. This violates the JWS specification, and because of that JJWT does not support it.
This is taken from this github issue, which I guess is same as you are facing.
Upvotes: 33