JSON Web Token (JWT) simple Examples

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.UUID;

//import org.jose4j.base64url.Base64;
import org.jose4j.json.JsonUtil;
import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jwk.RsaJwkGenerator;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.MalformedClaimException;
import org.jose4j.jwt.NumericDate;
import org.jose4j.jwt.consumer.ErrorCodes;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;

public class OpenIDConnectMain {

	public static void main(String[] args) throws JoseException, MalformedClaimException {

		//Generate keyId, use 32-bit uuid.
		String keyId = UUID.randomUUID().toString().replaceAll("-", "");
		System.out.println("keyId=" + keyId);

		//generate public and private key pair
		RsaJsonWebKey jwk = RsaJwkGenerator.generateJwk (2048);
		jwk.setKeyId (keyId);
		jwk.setAlgorithm(AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
		
		// public key
		String publicKeyText = jwk.toJson (JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
		System.out.println("publicKeyText====="+publicKeyText);
		
		//private key
		String privateKeyText = jwk.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
		System.out.println("privateKeyText====="+privateKeyText);
		
		//Signed by private key, generate token
		String idToken = createIdToken(keyId, privateKeyText);
		verifyIdToken(publicKeyText, idToken);
	}

	//Use the public key to verify the token signature and parse the content of the token.
	private static void verifyIdToken(String publicKeyText, String idToken)
			throws JoseException, MalformedClaimException {

		//Parse the header information (this operation does not require a public key)
		JsonWebSignature jwo = (JsonWebSignature) JsonWebSignature.fromCompactSerialization(idToken);
		String alg = jwo.getHeader("alg");
		
		//The API gateway obtains the publicKey according to the kid (when registering the authentication API, the keyId and publicKey are configured)
		String kid = jwo.getHeader("kid");

		PublicKey publicKey = new RsaJsonWebKey(JsonUtil.parseJson(publicKeyText)).getPublicKey();

		JwtConsumer jwtConsumer = new JwtConsumerBuilder().setRequireExpirationTime() // the
				.setAllowedClockSkewInSeconds(30) // allow some leeway in
				.setRequireSubject() // the JWT must have a subject claim
				.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
				.setExpectedAudience("Audience") // to whom the JWT is intended
				.setVerificationKey(publicKey) // verify the signature with the public key
				.setJwsAlgorithmConstraints( // only allow the expected signature algorithm(s) in the given context
						new AlgorithmConstraints(ConstraintType.WHITELIST, alg))
				.build(); // create the JwtConsumer instance

		try {
			// Validate the JWT and process it to the Claims
			JwtClaims jwtClaims = jwtConsumer.processToClaims(idToken);
			System.out.println("JWT validation succeeded! " + jwtClaims);
		} catch (InvalidJwtException e) {
			// InvalidJwtException will be thrown, if the JWT failed processing
			// or validation in anyway.
			// Hopefully with meaningful explanations(s) about what went wrong.
			System.out.println("Invalid JWT! " + e);

			// Programmatic access to (some) specific reasons for JWT invalidity
			// is also possible
			// should you want different error handling behavior for certain
			// conditions.

			// Whether or not the JWT has expired being one common reason for
			// invalidity
			if (e.hasExpired()) {
				System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());
			}

			// Or maybe the audience was invalid
			if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID)) {
				System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());
			}
		}
	}

	// https://bitbucket.org/b_c/jose4j/wiki/JWT%20Examples
	private static String createIdToken(String keyId, String privateKeyText) throws JoseException {


		// claims
		JwtClaims claims = new JwtClaims();
		claims.setGeneratedJwtId();
		claims.setIssuedAtToNow ();
		// expire time
		NumericDate date = NumericDate.now();
		date.addSeconds(120000);//1.3 days
		claims.setExpirationTime(date);
		claims.setNotBeforeMinutesInThePast(1);
		claims.setIssuer("Issuer"); // who creates the token and signs it
		claims.setSubject("Subject");
		claims.setAudience("Audience");
		// add custom parameters
		claims.setClaim("UserKey1", "UserVal1");

		// jws
		JsonWebSignature jws = new JsonWebSignature();
		jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
		jws.setKeyIdHeaderValue(keyId);
		jws.setPayload(claims.toJson());
		PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyText)).getPrivateKey();
		jws.setKey(privateKey);
		System.out.println("createIdToken::jws=" + jws);

		// idToken
		String idToken = jws.getCompactSerialization();
		System.out.println("createIdToken::idToken=" + idToken);

		return idToken;
	}

}

 

The jose.4.j library is an open source (Apache 2.0) implementation of JWT 

 

id_token, also called ID Token, is a token defined in the OIDC protocol.

id_token generation requires KeyPair, keyId and Claims.

The main extension of OIDC to OAuth2 is to provide ID Token.

ID Token is a security token, which is a data structure in JWT format provided by an authorization server that contains user information ( consisting of a set of Cliams and other auxiliary Cliams ).

 

The main components of ID Token are as follows (OIDC using OAuth2 flow).

iss = Issuer Identifier: Required . The unique identifier of the person who provided the authentication information. Usually a https url (excluding querystring and fragment parts).

sub = Subject Identifier: Required . The EU logo provided by iss is unique within the scope of iss. It will be used by the RP to identify a unique user. Up to 255 ASCII characters.

aud = Audience(s): Required . Identify the audience of the ID Token. Must contain OAuth2 client_id.

exp = Expiration time: Required . Expiration time, the ID Token that exceeds this time will be invalid and will no longer be verified.

iat = Issued At Time: Required . The time the JWT was constructed.

auth_time = AuthenticationTime: The time when the EU completed the authentication. If the RP sends the AuthN request with the max_age parameter, this claim is required.

nonce: The random string provided by the RP when sending the request to slow down replay attacks, and it can also be used to associate the ID Token with the session information of the RP itself.

acr = Authentication Context Class Reference: Optional. Represents an authentication context reference value that can be used to identify the authentication context class.

amr = Authentication Methods References: Optional. Represents a set of authentication methods.

azp = Authorized party: Optional. Use in conjunction with aud. This value is only used when the authenticated party and the audience (aud) do not agree, and are rarely used in general.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326232125&siteId=291194637