This is an automated email from the ASF dual-hosted git repository.

smolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new 2426bd4  KNOX-2703 - Configuring JWT type at creation/verification 
time (#532)
2426bd4 is described below

commit 2426bd493feef9fd6d3f3041cfbaea7503e4c15e
Author: Sandor Molnar <[email protected]>
AuthorDate: Tue Jan 18 19:36:31 2022 +0100

    KNOX-2703 - Configuring JWT type at creation/verification time (#532)
---
 .../hadoopauth/filter/HadoopAuthFilterTest.java    |  1 +
 .../federation/jwt/filter/AbstractJWTFilter.java   |  4 +-
 .../federation/jwt/filter/JWTFederationFilter.java | 12 ++++++
 .../provider/federation/AbstractJWTFilterTest.java |  3 +-
 gateway-release/home/conf/topologies/homepage.xml  |  4 ++
 .../token/impl/DefaultTokenAuthorityService.java   | 11 ++++-
 .../service/knoxsso/WebSSOResourceTest.java        |  4 +-
 .../gateway/service/knoxtoken/TokenResource.java   |  8 +++-
 .../knoxtoken/TokenServiceResourceTest.java        |  3 +-
 .../services/security/token/JWTokenAttributes.java |  9 +++-
 .../security/token/JWTokenAttributesBuilder.java   |  8 +++-
 .../services/security/token/JWTokenAuthority.java  |  5 ++-
 .../gateway/services/security/token/impl/JWT.java  |  3 ++
 .../services/security/token/impl/JWTToken.java     | 48 ++++++++++++++--------
 .../services/security/token/impl/JWTTokenTest.java | 25 +++++++----
 15 files changed, 115 insertions(+), 33 deletions(-)

diff --git 
a/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java
 
b/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java
index 355005a..25a504f 100644
--- 
a/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java
+++ 
b/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java
@@ -564,6 +564,7 @@ public class HadoopAuthFilterTest {
       
expect(filterConfig.getInitParameter(JWTFederationFilter.JWT_UNAUTHENTICATED_PATHS_PARAM)).andReturn(null).anyTimes();
       
expect(filterConfig.getInitParameter(AbstractJWTFilter.JWT_EXPECTED_ISSUER)).andReturn(null).anyTimes();
       
expect(filterConfig.getInitParameter(AbstractJWTFilter.JWT_EXPECTED_SIGALG)).andReturn(null).anyTimes();
+      
expect(filterConfig.getInitParameter(JWTFederationFilter.ALLOWED_JWS_TYPES)).andReturn(null).anyTimes();
       
expect(filterConfig.getInitParameter(SignatureVerificationCache.TOKENS_VERIFIED_CACHE_MAX)).andReturn(null).anyTimes();
     }
 
diff --git 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
index a8da01a..01412e4 100644
--- 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
+++ 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
@@ -72,6 +72,7 @@ import 
org.apache.knox.gateway.services.security.token.impl.JWT;
 import org.apache.knox.gateway.services.security.token.impl.JWTToken;
 import org.apache.knox.gateway.services.security.token.impl.TokenMAC;
 
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSHeader;
 import org.apache.knox.gateway.util.Tokens;
 
@@ -105,6 +106,7 @@ public abstract class AbstractJWTFilter implements Filter {
   private String expectedSigAlg;
   protected String expectedPrincipalClaim;
   protected String expectedJWKSUrl;
+  protected Set<JOSEObjectType> allowedJwsTypes;
 
   private TokenStateService tokenStateService;
   private TokenMAC tokenMAC;
@@ -451,7 +453,7 @@ public abstract class AbstractJWTFilter implements Filter {
         if (publicKey != null) {
           verified = authority.verifyToken(token, publicKey);
         } else if (expectedJWKSUrl != null) {
-          verified = authority.verifyToken(token, expectedJWKSUrl, 
expectedSigAlg);
+          verified = authority.verifyToken(token, expectedJWKSUrl, 
expectedSigAlg, allowedJwsTypes);
         } else {
           verified = authority.verifyToken(token);
         }
diff --git 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
index bdb0e6e..60914d6 100644
--- 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
+++ 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
@@ -26,6 +26,7 @@ import java.util.Base64;
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import javax.security.auth.Subject;
 import javax.servlet.FilterChain;
@@ -46,6 +47,8 @@ import 
org.apache.knox.gateway.services.security.token.impl.JWTToken;
 import org.apache.knox.gateway.util.AuthFilterUtils;
 import org.apache.knox.gateway.util.CertificateUtils;
 
+import com.nimbusds.jose.JOSEObjectType;
+
 public class JWTFederationFilter extends AbstractJWTFilter {
 
   private static final JWTMessages LOGGER = MessagesFactory.get( 
JWTMessages.class );
@@ -61,6 +64,7 @@ public class JWTFederationFilter extends AbstractJWTFilter {
   public static final String KNOX_TOKEN_QUERY_PARAM_NAME = 
"knox.token.query.param.name";
   public static final String TOKEN_PRINCIPAL_CLAIM = 
"knox.token.principal.claim";
   public static final String JWKS_URL = "knox.token.jwks.url";
+  public static final String ALLOWED_JWS_TYPES = 
"knox.token.allowed.jws.types";
   public static final String BEARER   = "Bearer ";
   public static final String BASIC    = "Basic";
   public static final String TOKEN    = "Token";
@@ -90,6 +94,14 @@ public class JWTFederationFilter extends AbstractJWTFilter {
       expectedJWKSUrl = oidcjwksurl;
     }
 
+    allowedJwsTypes = new HashSet<>();
+    final String allowedTypes = 
filterConfig.getInitParameter(ALLOWED_JWS_TYPES);
+    if (allowedTypes != null) {
+      Stream.of(allowedTypes.trim().split(",")).forEach(allowedType -> 
allowedJwsTypes.add(new JOSEObjectType(allowedType.trim())));
+    } else {
+      allowedJwsTypes.add(JOSEObjectType.JWT);
+    }
+
     // expected claim
     String oidcPrincipalclaim = 
filterConfig.getInitParameter(TOKEN_PRINCIPAL_CLAIM);
     if (oidcPrincipalclaim != null) {
diff --git 
a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java
 
b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java
index 18b802d..8a2bffb 100644
--- 
a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java
+++ 
b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java
@@ -17,6 +17,7 @@
  */
 package org.apache.knox.gateway.provider.federation;
 
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.JWSHeader;
 import com.nimbusds.jose.JWSSigner;
@@ -1053,7 +1054,7 @@ public abstract class AbstractJWTFilterTest  {
     }
 
     @Override
-    public boolean verifyToken(JWT token, String jwksurl, String algorithm) {
+    public boolean verifyToken(JWT token, String jwksurl, String algorithm, 
Set<JOSEObjectType> allowedJwsTypes) {
      return false;
     }
   }
diff --git a/gateway-release/home/conf/topologies/homepage.xml 
b/gateway-release/home/conf/topologies/homepage.xml
index 49d259f..b70d34e 100644
--- a/gateway-release/home/conf/topologies/homepage.xml
+++ b/gateway-release/home/conf/topologies/homepage.xml
@@ -97,6 +97,10 @@
           <name>knox.token.renewer.whitelist</name>
           <value>admin</value>
       </param>
+      <param>
+          <name>knox.token.type</name>
+          <value>JWT</value>
+      </param>
    </service>
    <application>
       <name>tokengen</name>
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
index 1e1e225..7c5c295 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
@@ -54,6 +54,7 @@ import 
org.apache.knox.gateway.services.security.token.impl.JWT;
 import org.apache.knox.gateway.services.security.token.impl.JWTToken;
 
 import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.JWSSigner;
 import com.nimbusds.jose.JWSVerifier;
@@ -65,6 +66,8 @@ import com.nimbusds.jose.crypto.RSASSAVerifier;
 import com.nimbusds.jose.jwk.source.JWKSource;
 import com.nimbusds.jose.jwk.source.RemoteJWKSet;
 import com.nimbusds.jose.proc.BadJOSEException;
+import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier;
+import com.nimbusds.jose.proc.JOSEObjectTypeVerifier;
 import com.nimbusds.jose.proc.JWSKeySelector;
 import com.nimbusds.jose.proc.JWSVerificationKeySelector;
 import com.nimbusds.jose.proc.SecurityContext;
@@ -119,7 +122,9 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
       claimArray[4] = cachedSigningKeyID.isPresent() ? 
cachedSigningKeyID.get() : null;
       claimArray[5] = jwtAttributes.getJku();
     }
-    final JWT token = SUPPORTED_PKI_SIG_ALGS.contains(algorithm) || 
SUPPORTED_HMAC_SIG_ALGS.contains(algorithm) ? new JWTToken(algorithm, 
claimArray, jwtAttributes.getAudiences(), jwtAttributes.isManaged()) : null;
+    final JWT token = SUPPORTED_PKI_SIG_ALGS.contains(algorithm) || 
SUPPORTED_HMAC_SIG_ALGS.contains(algorithm)
+        ? new JWTToken(algorithm, claimArray, jwtAttributes.getAudiences(), 
jwtAttributes.isManaged(), jwtAttributes.getType())
+        : null;
     if (token != null) {
       if (SUPPORTED_HMAC_SIG_ALGS.contains(algorithm)) {
         signTokenWithHMAC(token);
@@ -228,7 +233,7 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
   }
 
   @Override
-  public boolean verifyToken(JWT token, String jwksurl, String algorithm) 
throws TokenServiceException {
+  public boolean verifyToken(JWT token, String jwksurl, String algorithm, 
Set<JOSEObjectType> allowedJwsTypes) throws TokenServiceException {
     boolean verified = false;
     try {
       if (algorithm != null && jwksurl != null) {
@@ -241,6 +246,8 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
         jwtProcessor.setJWSKeySelector(keySelector);
         JWTClaimsSetVerifier<SecurityContext> claimsVerifier = new 
DefaultJWTClaimsVerifier<>();
         jwtProcessor.setJWTClaimsSetVerifier(claimsVerifier);
+        final JOSEObjectTypeVerifier<SecurityContext> objectTypeVerifier = new 
DefaultJOSEObjectTypeVerifier<>(allowedJwsTypes);
+        jwtProcessor.setJWSTypeVerifier(objectTypeVerifier);
 
         // Process the token
         SecurityContext ctx = null; // optional context parameter, not 
required here
diff --git 
a/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java
 
b/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java
index 6e8ba26..a28a589 100644
--- 
a/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java
+++ 
b/gateway-service-knoxsso/src/test/java/org/apache/knox/gateway/service/knoxsso/WebSSOResourceTest.java
@@ -18,6 +18,7 @@
 package org.apache.knox.gateway.service.knoxsso;
 
 import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSSigner;
 import com.nimbusds.jose.JWSVerifier;
 import com.nimbusds.jose.KeyLengthException;
@@ -66,6 +67,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static 
org.apache.knox.gateway.services.GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE;
 import static org.junit.Assert.assertEquals;
@@ -816,7 +818,7 @@ public class WebSSOResourceTest {
     }
 
     @Override
-    public boolean verifyToken(JWT token, String jwksurl, String algorithm) {
+    public boolean verifyToken(JWT token, String jwksurl, String algorithm, 
Set<JOSEObjectType> allowedJwsTypes) {
      return false;
     }
   }
diff --git 
a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
 
b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
index c93f31c..d083c8e 100644
--- 
a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
+++ 
b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
@@ -98,6 +98,7 @@ public class TokenResource {
   private static final String ENDPOINT_PUBLIC_CERT = "endpoint_public_cert";
   private static final String BEARER = "Bearer";
   private static final String TOKEN_TTL_PARAM = "knox.token.ttl";
+  private static final String TOKEN_TYPE_PARAM = "knox.token.type";
   private static final String TOKEN_AUDIENCES_PARAM = "knox.token.audiences";
   private static final String TOKEN_TARGET_URL = "knox.token.target.url";
   static final String TOKEN_CLIENT_DATA = "knox.token.client.data";
@@ -128,6 +129,7 @@ public class TokenResource {
   private static final String TARGET_ENDPOINT_PULIC_CERT_PEM = 
"knox.token.target.endpoint.cert.pem";
   private static TokenServiceMessages log = 
MessagesFactory.get(TokenServiceMessages.class);
   private long tokenTTL = TOKEN_TTL_DEFAULT;
+  private String tokenType;
   private String tokenTTLAsText;
   private List<String> targetAudiences = new ArrayList<>();
   private String tokenTargetUrl;
@@ -211,6 +213,9 @@ public class TokenResource {
         log.invalidTokenTTLEncountered(ttl);
       }
     }
+
+    this.tokenType = context.getInitParameter(TOKEN_TYPE_PARAM);
+
     tokenTTLAsText = getTokenTTLAsText();
 
     tokenTargetUrl = context.getInitParameter(TOKEN_TARGET_URL);
@@ -666,7 +671,8 @@ public class TokenResource {
           .setAlgorithm(signatureAlgorithm)
           .setExpires(expires)
           .setManaged(managedToken)
-          .setJku(jku);
+          .setJku(jku)
+          .setType(tokenType);
       if (!targetAudiences.isEmpty()) {
         jwtAttributesBuilder.setAudiences(targetAudiences);
       }
diff --git 
a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
 
b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
index 84f1efd..d895a53 100644
--- 
a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
+++ 
b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
@@ -28,6 +28,7 @@ import static org.junit.Assert.fail;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.JWSSigner;
 import com.nimbusds.jose.JWSVerifier;
@@ -1513,7 +1514,7 @@ public class TokenServiceResourceTest {
     }
 
     @Override
-    public boolean verifyToken(JWT token, String jwksurl, String algorithm) {
+    public boolean verifyToken(JWT token, String jwksurl, String algorithm, 
Set<JOSEObjectType> allowedJwsTypes) {
      return false;
     }
   }
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributes.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributes.java
index 0d5fb90..6f3a9fa 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributes.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributes.java
@@ -31,9 +31,10 @@ public class JWTokenAttributes {
   private final char[] signingKeystorePassphrase;
   private final boolean managed;
   private final String jku;
+  private final String type;
 
   JWTokenAttributes(Principal principal, List<String> audiences, String 
algorithm, long expires, String signingKeystoreName, String 
signingKeystoreAlias,
-      char[] signingKeystorePassphrase, boolean managed, String jku) {
+      char[] signingKeystorePassphrase, boolean managed, String jku, String 
type) {
     super();
     this.principal = principal;
     this.audiences = audiences;
@@ -44,6 +45,7 @@ public class JWTokenAttributes {
     this.signingKeystorePassphrase = signingKeystorePassphrase;
     this.managed = managed;
     this.jku = jku;
+    this.type = type;
   }
 
   public Principal getPrincipal() {
@@ -81,4 +83,9 @@ public class JWTokenAttributes {
   public String getJku() {
     return jku;
   }
+
+  public String getType() {
+    return type;
+  }
+
 }
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributesBuilder.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributesBuilder.java
index 0c053f0..feb0758 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributesBuilder.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributesBuilder.java
@@ -34,6 +34,7 @@ public class JWTokenAttributesBuilder {
   private char[] signingKeystorePassphrase;
   private boolean managed;
   private String jku;
+  private String type;
 
   public JWTokenAttributesBuilder setPrincipal(Subject subject) {
     return setPrincipal((Principal) subject.getPrincipals().toArray()[0]);
@@ -88,9 +89,14 @@ public class JWTokenAttributesBuilder {
     return this;
   }
 
+  public JWTokenAttributesBuilder setType(String type) {
+    this.type = type;
+    return this;
+  }
+
   public JWTokenAttributes build() {
     return new JWTokenAttributes(principal, (audiences == null ? 
Collections.emptyList() : audiences), algorithm, expires, signingKeystoreName, 
signingKeystoreAlias,
-        signingKeystorePassphrase, managed, jku);
+        signingKeystorePassphrase, managed, jku, type);
   }
 
 }
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAuthority.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAuthority.java
index 837cd11..ccd74c7 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAuthority.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAuthority.java
@@ -18,9 +18,12 @@
 package org.apache.knox.gateway.services.security.token;
 
 import java.security.interfaces.RSAPublicKey;
+import java.util.Set;
 
 import org.apache.knox.gateway.services.security.token.impl.JWT;
 
+import com.nimbusds.jose.JOSEObjectType;
+
 public interface JWTokenAuthority {
 
   JWT issueToken(JWTokenAttributes jwtAttributes) throws TokenServiceException;
@@ -29,5 +32,5 @@ public interface JWTokenAuthority {
 
   boolean verifyToken(JWT token, RSAPublicKey publicKey) throws 
TokenServiceException;
 
-  boolean verifyToken(JWT token, String jwksurl, String algorithm) throws 
TokenServiceException;
+  boolean verifyToken(JWT token, String jwksurl, String algorithm, 
Set<JOSEObjectType> allowedJwsTypes) throws TokenServiceException;
 }
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWT.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWT.java
index 51e4013..e416e63 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWT.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWT.java
@@ -19,6 +19,7 @@ package org.apache.knox.gateway.services.security.token.impl;
 
 import java.util.Date;
 
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.JWSSigner;
 import com.nimbusds.jose.JWSVerifier;
@@ -62,6 +63,8 @@ public interface JWT {
 
   JWSAlgorithm getSignatureAlgorithm();
 
+  JOSEObjectType getType();
+
   void sign(JWSSigner signer);
 
   boolean verify(JWSVerifier verifier);
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
index 2ab990d..281bed2 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
@@ -27,6 +27,7 @@ import java.util.UUID;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 
 import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.JWSHeader;
 import com.nimbusds.jose.JWSSigner;
@@ -68,19 +69,29 @@ public class JWTToken implements JWT {
   }
 
   public JWTToken(String alg, String[] claimsArray, List<String> audiences, 
boolean managed) {
+    this(alg, claimsArray, audiences, managed, null);
+  }
+
+  public JWTToken(String alg, String[] claimsArray, List<String> audiences, 
boolean managed, String type) {
+    if(claimsArray == null) {
+      log.missingClaims(-1);
+    } else if (claimsArray.length < 6){
+      log.missingClaims(claimsArray.length);
+    }
+
     JWSHeader header = null;
     try {
       header = new JWSHeader(new JWSAlgorithm(alg),
+      type == null ? null : new JOSEObjectType(type),
       null,
       null,
-      null,
-      claimsArray[5] != null ? new URI(claimsArray[5]) : null, // JKU
+      getClaimValue(claimsArray, 5) != null ? new 
URI(getClaimValue(claimsArray, 5)) : null, // JKU
       null,
       null,
       null,
       null,
       null,
-      claimsArray[4] != null ? claimsArray[4] : null, // KID
+      getClaimValue(claimsArray, 4) != null ? getClaimValue(claimsArray, 4) : 
null, // KID
       null,
       null);
     } catch (URISyntaxException e) {
@@ -88,29 +99,25 @@ public class JWTToken implements JWT {
       header = new JWSHeader(new JWSAlgorithm(alg));
     }
 
-    if(claimsArray == null || claimsArray.length < 6) {
-      log.missingClaims(claimsArray.length);
-    }
-
-    if (claimsArray[2] != null) {
+    if (getClaimValue(claimsArray, 2) != null) {
       if (audiences == null) {
         audiences = new ArrayList<>();
       }
-      audiences.add(claimsArray[2]);
+      audiences.add(getClaimValue(claimsArray, 2));
     }
     JWTClaimsSet claims;
     JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder()
-    .issuer(claimsArray[0])
-    .subject(claimsArray[1])
+    .issuer(getClaimValue(claimsArray, 0))
+    .subject(getClaimValue(claimsArray, 1))
     .audience(audiences);
-    if(claimsArray[3] != null) {
+    if(getClaimValue(claimsArray, 3) != null) {
       builder = builder.expirationTime(new 
Date(Long.parseLong(claimsArray[3])));
     }
-    if(claimsArray[4] != null) {
-      builder.claim(KNOX_KID_CLAIM, claimsArray[4]);
+    if(getClaimValue(claimsArray, 4) != null) {
+      builder.claim(KNOX_KID_CLAIM, getClaimValue(claimsArray, 4));
     }
-    if(claimsArray[5] != null) {
-      builder.claim(KNOX_JKU_CLAIM, claimsArray[5]);
+    if(getClaimValue(claimsArray, 5) != null) {
+      builder.claim(KNOX_JKU_CLAIM, getClaimValue(claimsArray, 5));
     }
 
     // Add a private UUID claim for uniqueness
@@ -122,6 +129,10 @@ public class JWTToken implements JWT {
     jwt = new SignedJWT(header, claims);
   }
 
+  private String getClaimValue(String[] claims, int index) {
+    return claims == null || claims.length <= index ? null : claims[index];
+  }
+
   @Override
   public String getHeader() {
     JWSHeader header = jwt.getHeader();
@@ -134,6 +145,11 @@ public class JWTToken implements JWT {
   }
 
   @Override
+  public JOSEObjectType getType() {
+    return jwt.getHeader().getType();
+  }
+
+  @Override
   public String getClaims() {
     String c = null;
     JWTClaimsSet claims;
diff --git 
a/gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
 
b/gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
index 24d3e71..d022cb7 100644
--- 
a/gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
+++ 
b/gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
@@ -17,6 +17,13 @@
  */
 package org.apache.knox.gateway.services.security.token.impl;
 
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.interfaces.RSAPrivateKey;
@@ -30,19 +37,13 @@ import java.util.UUID;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import com.nimbusds.jose.JOSEObjectType;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.JWSSigner;
 import com.nimbusds.jose.JWSVerifier;
 import com.nimbusds.jose.crypto.RSASSASigner;
 import com.nimbusds.jose.crypto.RSASSAVerifier;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 public class JWTTokenTest {
   private static final String JWT_TOKEN = 
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E";
   private static final String HEADER = "{\"typ\":\"JWT\",\"alg\":\"HS256\"}";
@@ -290,4 +291,14 @@ public class JWTTokenTest {
           ex.getMessage());
     }
   }
+
+  @Test
+  public void testTokenType() throws Exception {
+    JWT token = new JWTToken("RS256", null, null, false, null);
+    assertNull(token.getType());
+
+    final String tokenType = "at+jwt";
+    token = new JWTToken("RS256", null, null, false, tokenType);
+    assertEquals(token.getType(), new JOSEObjectType(tokenType));
+  }
 }

Reply via email to