Can You Read Tokens From a Read String in Java

Java JWT

CircleCI Coverage Status License Javadoc

A Java implementation of JSON Web Token (JWT) - RFC 7519.

If you're looking for an Android version of the JWT Decoder accept a wait at our JWTDecode.Android library.

This library requires Coffee 8 or higher. The concluding version that supported Java seven was three.11.0.

Installation

The library is available on both Maven Cardinal and Bintray, and the Javadoc is published here.

Maven

<dependency>     <groupId>com.auth0</groupId>     <artifactId>coffee-jwt</artifactId>     <version>3.18.iii</version> </dependency>

Gradle

implementation                              'com.auth0:java-jwt:3.18.iii'                          

Available Algorithms

The library implements JWT Verification and Signing using the post-obit algorithms:

JWS Algorithm Clarification
HS256 HMAC256 HMAC with SHA-256
HS384 HMAC384 HMAC with SHA-384
HS512 HMAC512 HMAC with SHA-512
RS256 RSA256 RSASSA-PKCS1-v1_5 with SHA-256
RS384 RSA384 RSASSA-PKCS1-v1_5 with SHA-384
RS512 RSA512 RSASSA-PKCS1-v1_5 with SHA-512
ES256 ECDSA256 ECDSA with curve P-256 and SHA-256
ES384 ECDSA384 ECDSA with curve P-384 and SHA-384
ES512 ECDSA512 ECDSA with curve P-521 and SHA-512

⚠️ Note - ECDSA with curve secp256k1 and SHA-256 will not be supported for Java fifteen+ by this library since information technology has been (disabled in Coffee xv)[https://www.oracle.com/java/technologies/javase/15-relnote-issues.html#JDK-8237219]

Usage

Pick the Algorithm

The Algorithm defines how a token is signed and verified. It can be instantiated with the raw value of the secret in the case of HMAC algorithms, or the primal pairs or KeyProvider in the case of RSA and ECDSA algorithms. Once created, the instance is reusable for token signing and verification operations.

When using RSA or ECDSA algorithms and you just need to sign JWTs y'all can avert specifying a Public Key by passing a null value. The same can be done with the Private Central when y'all merely need to verify JWTs.

Using static secrets or keys:

                              //HMAC              Algorithm              algorithmHS              =              Algorithm                              .HMAC256(                "secret"              );                              //RSA              RSAPublicKey              publicKey              =                              //Get the central instance              RSAPrivateKey              privateKey              =                              //Go the key instance              Algorithm              algorithmRS              =              Algorithm                              .RSA256(publicKey, privateKey);

Note: How you lot obtain or read keys is non in the scope of this library. For an example of how you might implement this, see this gist.

HMAC Primal Length and Security

When using a Hash-based Message Authenticaton Code, e.g. HS256 or HS512, in social club to comply with the strict requirements of the JSON Web Algorithms (JWA) specification (RFC7518), y'all must use a secret fundamental which has the same (or larger) fleck length equally the size of the output hash. This is to avert weakening the security strength of the authentication code (see NIST recomendations NIST SP 800-117). For example, when using HMAC256, the clandestine key length must exist a minimum of 256 bits.

Using a KeyProvider:

Past using a KeyProvider you can alter in runtime the key used either to verify the token signature or to sign a new token for RSA or ECDSA algorithms. This is achieved by implementing either RSAKeyProvider or ECDSAKeyProvider methods:

  • getPublicKeyById(String kid): Its chosen during token signature verification and information technology should return the key used to verify the token. If primal rotation is existence used, e.one thousand. JWK it can fetch the correct rotation fundamental using the id. (Or just return the same key all the fourth dimension).
  • getPrivateKey(): Its chosen during token signing and it should return the key that will be used to sign the JWT.
  • getPrivateKeyId(): Its called during token signing and it should render the id of the central that identifies the one returned past getPrivateKey(). This value is preferred over the 1 set in the JWTCreator.Builder#withKeyId(String) method. If yous don't demand to set a child value avoid instantiating an Algorithm using a KeyProvider.

The post-obit case shows how this would work with JwkStore, an imaginary JWK Ready implementation. For simple key rotation using JWKS, try the jwks-rsa-coffee library.

              terminal              JwkStore              jwkStore              =              new              JwkStore(                "{JWKS_FILE_HOST}"              );              final              RSAPrivateKey              privateKey              =                              //Get the key instance              final              Cord              privateKeyId              =                              //Create an Id for the higher up key              RSAKeyProvider              keyProvider              =              new              RSAKeyProvider() {              @Override              public              RSAPublicKey              getPublicKeyById(String              kid) {                              //Received 'kid' value might be zip if it wasn't defined in the Token'due south header              RSAPublicKey              publicKey              =              jwkStore.become(child);              render              (RSAPublicKey) publicKey;     }              @Override              public              RSAPrivateKey              getPrivateKey() {              return              privateKey;     }              @Override              public              String              getPrivateKeyId() {              return              privateKeyId;     } };              Algorithm              algorithm              =              Algorithm                              .RSA256(keyProvider);                              //Use the Algorithm to create and verify JWTs.            

Create and Sign a Token

You'll get-go demand to create a JWTCreator instance by calling JWT.create(). Use the builder to define the custom Claims your token needs to have. Finally to go the String token call sign() and pass the Algorithm instance.

  • Example using HS256

                      try                  {                  Algorithm                  algorithm                  =                  Algorithm                                      .HMAC256(                    "hugger-mugger"                  );                  String                  token                  =                  JWT                  .create()         .withIssuer(                    "auth0"                  )         .sign(algorithm); }                  catch                  (JWTCreationException                  exception){                                      //Invalid Signing configuration / Couldn't convert Claims.                  }
  • Case using RS256

                      RSAPublicKey                  publicKey                  =                                      //Go the key instance                  RSAPrivateKey                  privateKey                  =                                      //Get the key instance                  try                  {                  Algorithm                  algorithm                  =                  Algorithm                                      .RSA256(publicKey, privateKey);                  String                  token                  =                  JWT                  .create()         .withIssuer(                    "auth0"                  )         .sign(algorithm); }                  grab                  (JWTCreationException                  exception){                                      //Invalid Signing configuration / Couldn't catechumen Claims.                  }

If a Merits couldn't be converted to JSON or the Key used in the signing procedure was invalid a JWTCreationException will raise.

Verify a Token

Yous'll first need to create a JWTVerifier example by calling JWT.require() and passing the Algorithm instance. If you require the token to have specific Claim values, use the builder to define them. The instance returned by the method build() is reusable, so you can define it one time and use it to verify different tokens. Finally telephone call verifier.verify() passing the token.

  • Case using HS256

                      String                  token                  =                                      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE"                  ;                  try                  {                  Algorithm                  algorithm                  =                  Algorithm                                      .HMAC256(                    "secret"                  );                  JWTVerifier                  verifier                  =                  JWT                  .require(algorithm)         .withIssuer(                    "auth0"                  )         .build();                                      //Reusable verifier example                  DecodedJWT                  jwt                  =                  verifier.verify(token); }                  catch                  (JWTVerificationException                  exception){                                      //Invalid signature/claims                  }
  • Example using RS256

                      String                  token                  =                                      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE"                  ;                  RSAPublicKey                  publicKey                  =                                      //Get the cardinal example                  RSAPrivateKey                  privateKey                  =                                      //Get the key instance                  try                  {                  Algorithm                  algorithm                  =                  Algorithm                                      .RSA256(publicKey, privateKey);                  JWTVerifier                  verifier                  =                  JWT                  .require(algorithm)         .withIssuer(                    "auth0"                  )         .build();                                      //Reusable verifier instance                  DecodedJWT                  jwt                  =                  verifier.verify(token); }                  catch                  (JWTVerificationException                  exception){                                      //Invalid signature/claims                  }

If the token has an invalid signature or the Claim requirement is not met, a JWTVerificationException will raise.

Time Validation

The JWT token may include DateNumber fields that tin be used to validate that:

  • The token was issued in a past date "iat" < TODAY
  • The token hasn't expired yet "exp" > TODAY and
  • The token can already be used. "nbf" < TODAY

When verifying a token the time validation occurs automatically, resulting in a JWTVerificationException existence throw when the values are invalid. If any of the previous fields are missing they won't be considered in this validation.

To specify a leeway window in which the Token should still exist considered valid, apply the acceptLeeway() method in the JWTVerifier builder and laissez passer a positive seconds value. This applies to every item listed above.

              JWTVerifier              verifier              =              JWT              .crave(algorithm)     .acceptLeeway(1)                              //                1 sec for nbf, iat and exp              .build();

You tin can also specify a custom value for a given Date claim and override the default one for only that merits.

              JWTVerifier              verifier              =              JWT              .crave(algorithm)     .acceptLeeway(1)                              //1 sec for nbf and iat              .acceptExpiresAt(5)                              //v secs for exp              .build();

If you demand to test this behaviour in your lib/app cast the Verification case to a BaseVerification to proceeds visibility of the verification.build() method that accepts a custom Clock. e.k.:

              BaseVerification              verification              =              (BaseVerification)              JWT              .crave(algorithm)     .acceptLeeway(one)     .acceptExpiresAt(5);              Clock              clock              =              new              CustomClock();                              //Must implement Clock interface              JWTVerifier              verifier              =              verification.build(clock);

Decode a Token

              String              token              =                              "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE"              ;              try              {              DecodedJWT              jwt              =              JWT              .decode(token); }              grab              (JWTDecodeException              exception){                              //Invalid token              }

If the token has an invalid syntax or the header or payload are not JSONs, a JWTDecodeException will raise.

Header Claims

Algorithm ("alg")

Returns the Algorithm value or null if it's non defined in the Header.

              String              algorithm              =              jwt.getAlgorithm();

Type ("typ")

Returns the Blazon value or nix if it's not defined in the Header.

              Cord              type              =              jwt.getType();

Content Blazon ("cty")

Returns the Content Type value or zero if it'south not defined in the Header.

              String              contentType              =              jwt.getContentType();

Key Id ("kid")

Returns the Key Id value or null if it's not defined in the Header.

              String              keyId              =              jwt.getKeyId();

Private Claims

Additional Claims defined in the token's Header can be obtained by calling getHeaderClaim() and passing the Claim name. A Merits will always be returned, even if it can't be found. You can check if a Claim'southward value is zilch by calling merits.isNull().

              Merits              claim              =              jwt.getHeaderClaim(                "possessor"              );

When creating a Token with the JWT.create() you can specify header Claims by calling withHeader() and passing both the map of claims.

              Map<Cord,                Object>              headerClaims              =              new              HashMap(); headerClaims.put(                "owner"              ,                              "auth0"              );              String              token              =              JWT              .create()         .withHeader(headerClaims)         .sign(algorithm);

The alg and typ values volition always exist included in the Header afterwards the signing process.

Payload Claims

Issuer ("iss")

Returns the Issuer value or null if it's not divers in the Payload.

              String              issuer              =              jwt.getIssuer();

Subject ("sub")

Returns the Subject value or null if it'south non divers in the Payload.

              String              subject              =              jwt.getSubject();

Audience ("aud")

Returns the Audience value or goose egg if it's not divers in the Payload.

              List<Cord>              audience              =              jwt.getAudience();

Expiration Time ("exp")

Returns the Expiration Time value or nada if it'south not defined in the Payload.

              Date              expiresAt              =              jwt.getExpiresAt();

Non Earlier ("nbf")

Returns the Non Before value or cipher if information technology's not divers in the Payload.

              Date              notBefore              =              jwt.getNotBefore();

Issued At ("iat")

Returns the Issued At value or null if it's non defined in the Payload.

              Date              issuedAt              =              jwt.getIssuedAt();

JWT ID ("jti")

Returns the JWT ID value or null if it's not defined in the Payload.

Private Claims

Boosted Claims divers in the token's Payload can be obtained past calling getClaims() or getClaim() and passing the Claim proper noun. A Merits volition ever be returned, even if information technology can't be found. You can bank check if a Claim's value is nothing past calling claim.isNull().

              Map<Cord,                Claim>              claims              =              jwt.getClaims();                              //Key is the Claim name              Merits              claim              =              claims.go(                "isAdmin"              );

or

              Claim              merits              =              jwt.getClaim(                "isAdmin"              );

When creating a Token with the JWT.create() you tin can specify a custom Claim by calling withClaim() and passing both the name and the value.

              String              token              =              JWT              .create()         .withClaim(                "proper name"              ,              123)         .withArrayClaim(                "array"              ,              new              Integer[]{ane,              2,              3})         .sign(algorithm);

Y'all can besides create a JWT by calling withPayload() and passing a map of claim names to values:

              Map<String,                Object>              payloadClaims              =              new              HashMap<>(); payloadClaims.put(                "@context"              ,                              "https://auth0.com/"              );              String              token              =              JWT              .create()         .withPayload(payloadClaims)         .sign(algorithm);

You can besides verify custom Claims on the JWT.require() by calling withClaim() and passing both the name and the required value.

              JWTVerifier              verifier              =              JWT              .crave(algorithm)     .withClaim(                "name"              ,              123)     .withArrayClaim(                "array"              ,              one,              2,              3)     .build();              DecodedJWT              jwt              =              verifier.verify(                "my.jwt.token"              );

Currently supported classes for custom JWT Claim creation and verification are: Boolean, Integer, Double, String, Date and Arrays of blazon Cord and Integer.

Claim Grade

The Merits class is a wrapper for the Claim values. It allows you to get the Claim as different class types. The available helpers are:

Primitives

  • asBoolean(): Returns the Boolean value or aught if it can't be converted.
  • asInt(): Returns the Integer value or nil if it can't exist converted.
  • asDouble(): Returns the Double value or nada if it tin can't be converted.
  • asLong(): Returns the Long value or aught if information technology can't be converted.
  • asString(): Returns the String value or zip if it can't exist converted.
  • asDate(): Returns the Date value or nix if it can't exist converted. This must be a NumericDate (Unix Epoch/Timestamp). Note that the JWT Standard specified that all the NumericDate values must be in seconds.

Custom Classes and Collections

To obtain a Claim as a Drove you'll demand to provide the Grade Blazon of the contents to convert from.

  • as(class): Returns the value parsed as Grade Type. For collections yous should use the asArray and asList methods.
  • asMap(): Returns the value parsed every bit Map<String, Object>.
  • asArray(class): Returns the value parsed every bit an Assortment of elements of type Class Type, or zip if the value isn't a JSON Assortment.
  • asList(form): Returns the value parsed as a Listing of elements of blazon Course Type, or null if the value isn't a JSON Assortment.

If the values can't be converted to the given Class Type a JWTDecodeException volition enhance.

What is Auth0?

Auth0 helps you to:

  • Add hallmark with multiple hallmark sources, either social like Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, among others, or enterprise identity systems like Windows Azure AD, Google Apps, Active Directory, ADFS or whatsoever SAML Identity Provider.
  • Add authentication through more traditional username/password databases.
  • Add support for linking different user accounts with the aforementioned user.
  • Support for generating signed Json Web Tokens to telephone call your APIs and period the user identity deeply.
  • Analytics of how, when and where users are logging in.
  • Pull data from other sources and add together it to the user profile, through JavaScript rules.

Create a free account in Auth0

  1. Go to Auth0 and click Sign Up.
  2. Use Google, GitHub or Microsoft Account to login.

Issue Reporting

If you accept found a bug or if you have a feature request, please report them at this repository bug section. Please do non report security vulnerabilities on the public GitHub consequence tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

Writer

Auth0

License

This projection is licensed under the MIT license. See the LICENSE file for more info.

thorntonfander.blogspot.com

Source: https://github.com/auth0/java-jwt

0 Response to "Can You Read Tokens From a Read String in Java"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel