You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by sm...@apache.org on 2021/03/16 13:17:55 UTC
[knox] branch master updated: KNOX-2553 - Adding the
'managed_token' flag in the issued JWT as well as the JSON response of our
KnoxToken service (#416)
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 2be0345 KNOX-2553 - Adding the 'managed_token' flag in the issued JWT as well as the JSON response of our KnoxToken service (#416)
2be0345 is described below
commit 2be034535c025daf71818f717bd784286e01dd65
Author: Sandor Molnar <sm...@apache.org>
AuthorDate: Tue Mar 16 14:17:47 2021 +0100
KNOX-2553 - Adding the 'managed_token' flag in the issued JWT as well as the JSON response of our KnoxToken service (#416)
In order to avoid adding new and confusing methods into JWTokenAuthority I introduced a model object to store possible JWT attributes and kept only one method to issue a token.
---
.../jwt/filter/JWTAccessTokenAssertionFilter.java | 5 +-
.../jwt/filter/JWTAuthCodeAssertionFilter.java | 3 +-
.../provider/federation/AbstractJWTFilterTest.java | 36 +--------
.../token/impl/DefaultTokenAuthorityService.java | 60 ++-------------
.../impl/DefaultTokenAuthorityServiceTest.java | 20 +++--
.../gateway/service/knoxsso/WebSSOResource.java | 6 +-
.../service/knoxsso/WebSSOResourceTest.java | 59 ++------------
.../gateway/service/knoxtoken/TokenResource.java | 13 +++-
.../knoxtoken/TokenServiceResourceTest.java | 51 ++----------
.../services/security/token/JWTokenAttributes.java | 79 +++++++++++++++++++
.../security/token/JWTokenAttributesBuilder.java | 90 ++++++++++++++++++++++
.../services/security/token/JWTokenAuthority.java | 27 +------
.../services/security/token/impl/JWTToken.java | 7 ++
13 files changed, 239 insertions(+), 217 deletions(-)
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
index df4783a..37644d0 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
@@ -38,6 +38,8 @@ import org.apache.knox.gateway.provider.federation.jwt.JWTMessages;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.registry.ServiceRegistry;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributes;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributesBuilder;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.apache.knox.gateway.services.security.token.impl.JWT;
@@ -146,7 +148,8 @@ public class JWTAccessTokenAssertionFilter extends AbstractIdentityAssertionFilt
};
JWT token;
try {
- token = authority.issueToken(p, serviceName, signatureAlgorithm, expires);
+ final JWTokenAttributes jwtAttributes = new JWTokenAttributesBuilder().setPrincipal(p).setAudiences(serviceName).setAlgorithm(signatureAlgorithm).setExpires(expires).build();
+ token = authority.issueToken(jwtAttributes);
// Coverity CID 1327961
if( token != null ) {
accessToken = token.toString();
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java
index cda9f16..ab03f42 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java
@@ -32,6 +32,7 @@ import org.apache.knox.gateway.filter.security.AbstractIdentityAssertionFilter;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.registry.ServiceRegistry;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributesBuilder;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.apache.knox.gateway.services.security.token.impl.JWT;
@@ -64,7 +65,7 @@ public class JWTAuthCodeAssertionFilter extends AbstractIdentityAssertionFilter
principalName = mapper.mapUserPrincipal(principalName);
JWT authCode;
try {
- authCode = authority.issueToken(subject, signatureAlgorithm);
+ authCode = authority.issueToken(new JWTokenAttributesBuilder().setPrincipal(subject).setAlgorithm(signatureAlgorithm).build());
// get the url for the token service
String url = null;
if (sr != 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 20324d6..3f6bc98 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
@@ -30,6 +30,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.knox.gateway.provider.federation.jwt.filter.AbstractJWTFilter;
import org.apache.knox.gateway.provider.federation.jwt.filter.SSOCookieFederationFilter;
import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributes;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.impl.JWT;
import org.apache.knox.gateway.services.security.token.impl.JWTToken;
@@ -1246,46 +1247,13 @@ public abstract class AbstractJWTFilterTest {
}
@Override
- public JWT issueToken(Subject subject, String algorithm) {
- return null;
- }
-
- @Override
- public JWT issueToken(Principal p, String algorithm) {
- return null;
- }
-
- @Override
- public JWT issueToken(Principal p, String audience, String algorithm) {
- return null;
- }
-
- @Override
public boolean verifyToken(JWT token) {
JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) verifyingKey);
return token.verify(verifier);
}
@Override
- public JWT issueToken(Principal p, String audience, String algorithm,
- long expires) {
- return null;
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm,
- long expires) {
- return null;
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm, long expires,
- String signingKeystoreName, String signingKeystoreAlias, char[] signingKeystorePassphrase) {
- return null;
- }
-
- @Override
- public JWT issueToken(Principal p, String algorithm, long expires) {
+ public JWT issueToken(JWTokenAttributes jwtAttributes) {
return null;
}
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 5b15825..76e65ab 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
@@ -24,22 +24,17 @@ import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.security.auth.Subject;
-
import org.apache.knox.gateway.GatewayResources;
import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.i18n.resources.ResourcesFactory;
@@ -49,6 +44,7 @@ import org.apache.knox.gateway.services.security.AliasService;
import org.apache.knox.gateway.services.security.AliasServiceException;
import org.apache.knox.gateway.services.security.KeystoreService;
import org.apache.knox.gateway.services.security.KeystoreServiceException;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributes;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.apache.knox.gateway.services.security.token.TokenUtils;
@@ -99,65 +95,25 @@ public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
}
@Override
- public JWT issueToken(Subject subject, String algorithm) throws TokenServiceException {
- Principal p = (Principal) subject.getPrincipals().toArray()[0];
- return issueToken(p, algorithm);
- }
-
- @Override
- public JWT issueToken(Principal p, String algorithm) throws TokenServiceException {
- return issueToken(p, null, algorithm);
- }
-
- @Override
- public JWT issueToken(Principal p, String algorithm, long expires) throws TokenServiceException {
- return issueToken(p, (String)null, algorithm, expires);
- }
-
- @Override
- public JWT issueToken(Principal p, String audience, String algorithm)
- throws TokenServiceException {
- return issueToken(p, audience, algorithm, -1);
- }
-
- @Override
- public JWT issueToken(Principal p, String audience, String algorithm, long expires)
- throws TokenServiceException {
- List<String> audiences = null;
- if (audience != null) {
- audiences = new ArrayList<>();
- audiences.add(audience);
- }
- return issueToken(p, audiences, algorithm, expires);
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm, long expires)
- throws TokenServiceException {
- return issueToken(p, audiences, algorithm, expires, null, null, null);
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm, long expires,
- String signingKeystoreName, String signingKeystoreAlias, char[] signingKeystorePassphrase)
- throws TokenServiceException {
+ public JWT issueToken(JWTokenAttributes jwtAttributes) throws TokenServiceException {
String[] claimArray = new String[4];
claimArray[0] = "KNOXSSO";
- claimArray[1] = p.getName();
+ claimArray[1] = jwtAttributes.getPrincipal().getName();
claimArray[2] = null;
- if (expires == -1) {
+ if (jwtAttributes.getExpires() == -1) {
claimArray[3] = null;
}
else {
- claimArray[3] = String.valueOf(expires);
+ claimArray[3] = String.valueOf(jwtAttributes.getExpires());
}
- final JWT token = SUPPORTED_PKI_SIG_ALGS.contains(algorithm) || SUPPORTED_HMAC_SIG_ALGS.contains(algorithm) ? new JWTToken(algorithm, claimArray, audiences) : null;
+ final String algorithm = jwtAttributes.getAlgorithm();
+ final JWT token = SUPPORTED_PKI_SIG_ALGS.contains(algorithm) || SUPPORTED_HMAC_SIG_ALGS.contains(algorithm) ? new JWTToken(algorithm, claimArray, jwtAttributes.getAudiences(), jwtAttributes.isManaged()) : null;
if (token != null) {
if (SUPPORTED_HMAC_SIG_ALGS.contains(algorithm)) {
signTokenWithHMAC(token);
} else {
- signTokenWithRSA(token, signingKeystoreName, signingKeystoreAlias, signingKeystorePassphrase);
+ signTokenWithRSA(token, jwtAttributes.getSigningKeystoreName(), jwtAttributes.getSigningKeystoreAlias(), jwtAttributes.getSigningKeystorePassphrase());
}
return token;
} else {
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityServiceTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityServiceTest.java
index 485f752..b3a62ed 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityServiceTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityServiceTest.java
@@ -29,6 +29,9 @@ import org.apache.knox.gateway.services.security.AliasService;
import org.apache.knox.gateway.services.security.MasterService;
import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
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.JWTokenAttributes;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributesBuilder;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.easymock.EasyMock;
@@ -84,9 +87,10 @@ public class DefaultTokenAuthorityServiceTest {
ta.init(config, new HashMap<>());
ta.start();
- JWT token = ta.issueToken(principal, "RS256");
+ JWT token = ta.issueToken(new JWTokenAttributesBuilder().setPrincipal(principal).setAlgorithm("RS256").setManaged(true).build());
assertEquals("KNOXSSO", token.getIssuer());
assertEquals("john.doe@example.com", token.getSubject());
+ assertTrue(Boolean.parseBoolean(token.getClaim(JWTToken.MANAGED_TOKEN_CLAIM)));
assertTrue(ta.verifyToken(token));
}
@@ -133,7 +137,8 @@ public class DefaultTokenAuthorityServiceTest {
ta.init(config, new HashMap<>());
ta.start();
- JWT token = ta.issueToken(principal, "https://login.example.com", "RS256");
+ JWT token = ta
+ .issueToken(new JWTokenAttributesBuilder().setPrincipal(principal).setAudiences("https://login.example.com").setAlgorithm("RS256").build());
assertEquals("KNOXSSO", token.getIssuer());
assertEquals("john.doe@example.com", token.getSubject());
assertEquals("https://login.example.com", token.getAudience());
@@ -183,7 +188,7 @@ public class DefaultTokenAuthorityServiceTest {
ta.init(config, new HashMap<>());
ta.start();
- JWT token = ta.issueToken(principal, null, "RS256");
+ JWT token = ta.issueToken(new JWTokenAttributesBuilder().setPrincipal(principal).setAlgorithm("RS256").build());
assertEquals("KNOXSSO", token.getIssuer());
assertEquals("john.doe@example.com", token.getSubject());
@@ -232,7 +237,7 @@ public class DefaultTokenAuthorityServiceTest {
ta.init(config, new HashMap<>());
ta.start();
- JWT token = ta.issueToken(principal, "RS512");
+ JWT token = ta.issueToken(new JWTokenAttributesBuilder().setPrincipal(principal).setAlgorithm("RS512").build());
assertEquals("KNOXSSO", token.getIssuer());
assertEquals("john.doe@example.com", token.getSubject());
assertTrue(token.getHeader().contains("RS512"));
@@ -280,7 +285,7 @@ public class DefaultTokenAuthorityServiceTest {
ta.setKeystoreService(ks);
ta.init(config, new HashMap<>());
- ta.issueToken(principal, "none");
+ ta.issueToken(new JWTokenAttributesBuilder().setPrincipal(principal).setAlgorithm("none").build());
}
@Test
@@ -333,8 +338,9 @@ public class DefaultTokenAuthorityServiceTest {
ta.setKeystoreService(ks);
ta.init(config, new HashMap<>());
- JWT token = ta.issueToken(principal, Collections.emptyList(), "RS256", -1,
- customSigningKeyName, customSigningKeyAlias, customSigningKeyPassphrase.toCharArray());
+ final JWTokenAttributes jwtAttributes = new JWTokenAttributesBuilder().setPrincipal(principal).setAudiences(Collections.emptyList()).setAlgorithm("RS256").setExpires(-1)
+ .setSigningKeystoreName(customSigningKeyName).setSigningKeystoreAlias(customSigningKeyAlias).setSigningKeystorePassphrase(customSigningKeyPassphrase.toCharArray()).build();
+ JWT token = ta.issueToken(jwtAttributes);
assertEquals("KNOXSSO", token.getIssuer());
assertEquals("john.doe@example.com", token.getSubject());
diff --git a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java
index 8f34fec..a902199 100644
--- a/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java
+++ b/gateway-service-knoxsso/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOResource.java
@@ -52,6 +52,8 @@ import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.security.AliasService;
import org.apache.knox.gateway.services.security.AliasServiceException;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributes;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributesBuilder;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.apache.knox.gateway.services.security.token.TokenUtils;
@@ -260,7 +262,9 @@ public class WebSSOResource {
signingKeystorePassphrase = as.getPasswordFromAliasForCluster(clusterName, signingKeystorePassphraseAlias);
}
- JWT token = tokenAuthority.issueToken(p, targetAudiences, signatureAlgorithm, getExpiry(), signingKeystoreName, signingKeystoreAlias, signingKeystorePassphrase);
+ final JWTokenAttributes jwtAttributes = new JWTokenAttributesBuilder().setPrincipal(p).setAudiences(targetAudiences).setAlgorithm(signatureAlgorithm).setExpires(getExpiry())
+ .setSigningKeystoreName(signingKeystoreName).setSigningKeystoreAlias(signingKeystoreAlias).setSigningKeystorePassphrase(signingKeystorePassphrase).build();
+ JWT token = tokenAuthority.issueToken(jwtAttributes);
// Coverity CID 1327959
if( token != null ) {
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 23054e7..b6671ec 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
@@ -31,6 +31,7 @@ import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributes;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.apache.knox.gateway.services.security.token.TokenUtils;
@@ -42,7 +43,6 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
-import javax.security.auth.Subject;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
@@ -60,7 +60,6 @@ import java.security.KeyPairGenerator;
import java.security.Principal;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
@@ -762,63 +761,27 @@ public class WebSSOResourceTest {
}
@Override
- public JWT issueToken(Subject subject, String algorithm)
- throws TokenServiceException {
- Principal p = (Principal) subject.getPrincipals().toArray()[0];
- return issueToken(p, algorithm);
- }
-
- @Override
- public JWT issueToken(Principal p, String algorithm)
- throws TokenServiceException {
- return issueToken(p, null, algorithm);
- }
-
- @Override
- public JWT issueToken(Principal p, String audience, String algorithm)
- throws TokenServiceException {
- return issueToken(p, audience, algorithm, -1);
- }
-
- @Override
public boolean verifyToken(JWT token) throws TokenServiceException {
return verifyToken(token, this.publicKey);
}
@Override
- public JWT issueToken(Principal p, String audience, String algorithm,
- long expires) throws TokenServiceException {
- List<String> audiences = null;
- if (audience != null) {
- audiences = new ArrayList<>();
- audiences.add(audience);
- }
- return issueToken(p, audiences, algorithm, expires);
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm,
- long expires) throws TokenServiceException {
- return issueToken(p, audiences, algorithm, expires, null, null, null);
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm, long expires,
- String signingKeystoreName, String signingKeystoreAlias, char[] signingKeystorePassphrase)
+ public JWT issueToken(JWTokenAttributes jwtAttributes)
throws TokenServiceException {
String[] claimArray = new String[4];
claimArray[0] = "KNOXSSO";
- claimArray[1] = p.getName();
+ claimArray[1] = jwtAttributes.getPrincipal().getName();
claimArray[2] = null;
- if (expires == -1) {
+ if (jwtAttributes.getExpires() == -1) {
claimArray[3] = null;
} else {
- claimArray[3] = String.valueOf(expires);
+ claimArray[3] = String.valueOf(jwtAttributes.getExpires());
}
- JWT token = new JWTToken(algorithm, claimArray, audiences);
+ JWT token = new JWTToken(jwtAttributes.getAlgorithm(), claimArray, jwtAttributes.getAudiences());
try {
- JWSSigner signer = useHMAC ? new MACSigner(HMAC_SECRET) : new RSASSASigner(getPrivateKey(signingKeystoreName, signingKeystoreAlias, signingKeystorePassphrase));
+ JWSSigner signer = useHMAC ? new MACSigner(HMAC_SECRET)
+ : new RSASSASigner(getPrivateKey(jwtAttributes.getSigningKeystoreName(), jwtAttributes.getSigningKeystoreAlias(), jwtAttributes.getSigningKeystorePassphrase()));
token.sign(signer);
} catch (KeyLengthException e) {
throw new TokenServiceException(e);
@@ -841,12 +804,6 @@ public class WebSSOResourceTest {
}
@Override
- public JWT issueToken(Principal p, String algorithm, long expiry)
- throws TokenServiceException {
- return issueToken(p, Collections.emptyList(), algorithm, expiry);
- }
-
- @Override
public boolean verifyToken(JWT token, RSAPublicKey publicKey) throws TokenServiceException {
try {
JWSVerifier verifier = useHMAC ? new MACVerifier(HMAC_SECRET) : new RSASSAVerifier(publicKey);
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 065cb93..e1a60e8 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
@@ -50,6 +50,8 @@ import org.apache.knox.gateway.services.security.AliasService;
import org.apache.knox.gateway.services.security.AliasServiceException;
import org.apache.knox.gateway.services.security.KeystoreService;
import org.apache.knox.gateway.services.security.KeystoreServiceException;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributes;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributesBuilder;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenServiceException;
import org.apache.knox.gateway.services.security.token.TokenStateService;
@@ -70,6 +72,7 @@ public class TokenResource {
private static final String TOKEN_TYPE = "token_type";
private static final String ACCESS_TOKEN = "access_token";
private static final String TOKEN_ID = "token_id";
+ private static final String MANAGED_TOKEN = "managed";
private static final String TARGET_URL = "target_url";
private static final String ENDPOINT_PUBLIC_CERT = "endpoint_public_cert";
private static final String BEARER = "Bearer";
@@ -395,11 +398,16 @@ public class TokenResource {
}
try {
+ final boolean managedToken = tokenStateService != null;
JWT token;
+ JWTokenAttributes jwtAttributes;
if (targetAudiences.isEmpty()) {
- token = ts.issueToken(p, signatureAlgorithm, expires);
+ jwtAttributes = new JWTokenAttributesBuilder().setPrincipal(p).setAlgorithm(signatureAlgorithm).setExpires(expires).setManaged(managedToken).build();
+ token = ts.issueToken(jwtAttributes);
} else {
- token = ts.issueToken(p, targetAudiences, signatureAlgorithm, expires);
+ jwtAttributes = new JWTokenAttributesBuilder().setPrincipal(p).setAudiences(targetAudiences).setAlgorithm(signatureAlgorithm).setExpires(expires)
+ .setManaged(managedToken).build();
+ token = ts.issueToken(jwtAttributes);
}
if (token != null) {
@@ -410,6 +418,7 @@ public class TokenResource {
HashMap<String, Object> map = new HashMap<>();
map.put(ACCESS_TOKEN, accessToken);
map.put(TOKEN_ID, tokenId);
+ map.put(MANAGED_TOKEN, String.valueOf(managedToken));
map.put(TOKEN_TYPE, BEARER);
map.put(EXPIRES_IN, expires);
if (tokenTargetUrl != null) {
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 9f27ef9..54e92a4 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
@@ -31,6 +31,7 @@ import org.apache.knox.gateway.services.ServiceLifecycleException;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.token.JWTokenAttributes;
import org.apache.knox.gateway.services.security.token.JWTokenAuthority;
import org.apache.knox.gateway.services.security.token.TokenStateService;
import org.apache.knox.gateway.services.security.token.TokenUtils;
@@ -179,7 +180,7 @@ public class TokenServiceResourceTest {
@Test
public void testGetToken() throws Exception {
- configureCommonExpectations(Collections.singletonMap("org.apache.knox.gateway.gateway.cluster", "test"));
+ configureCommonExpectations(Collections.singletonMap("org.apache.knox.gateway.gateway.cluster", "test"), Boolean.TRUE);
TokenResource tr = new TokenResource();
tr.context = context;
@@ -199,6 +200,7 @@ public class TokenServiceResourceTest {
assertNotNull(expiry);
assertNotNull(getTagValue(retString, "token_id"));
+ assertTrue(Boolean.parseBoolean(getTagValue(retString, "managed")));
// Verify the token
JWT parsedToken = new JWTToken(accessToken);
@@ -1151,67 +1153,30 @@ public class TokenServiceResourceTest {
}
@Override
- public JWT issueToken(Subject subject, String algorithm) {
- Principal p = (Principal) subject.getPrincipals().toArray()[0];
- return issueToken(p, algorithm);
- }
-
- @Override
- public JWT issueToken(Principal p, String algorithm) {
- return issueToken(p, null, algorithm);
- }
-
- @Override
- public JWT issueToken(Principal p, String audience, String algorithm) {
- return issueToken(p, audience, algorithm, -1);
- }
-
- @Override
public boolean verifyToken(JWT token) {
JWSVerifier verifier = new RSASSAVerifier(publicKey);
return token.verify(verifier);
}
@Override
- public JWT issueToken(Principal p, String audience, String algorithm,
- long expires) {
- ArrayList<String> audiences = null;
- if (audience != null) {
- audiences = new ArrayList<>();
- audiences.add(audience);
- }
- return issueToken(p, audiences, algorithm, expires);
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm, long expires,
- String signingkeyName, String signingkeyAlias, char[] signingkeyPassphrase) {
- return issueToken(p, audiences, algorithm, expires);
- }
-
- @Override
- public JWT issueToken(Principal p, List<String> audiences, String algorithm, long expires) {
+ public JWT issueToken(JWTokenAttributes jwtAttributes) {
String[] claimArray = new String[4];
claimArray[0] = "KNOXSSO";
- claimArray[1] = p.getName();
+ claimArray[1] = jwtAttributes.getPrincipal().getName();
claimArray[2] = null;
- if (expires == -1) {
+ if (jwtAttributes.getExpires() == -1) {
claimArray[3] = null;
} else {
- claimArray[3] = String.valueOf(expires);
+ claimArray[3] = String.valueOf(jwtAttributes.getExpires());
}
- JWT token = new JWTToken(algorithm, claimArray, audiences);
+ JWT token = new JWTToken(jwtAttributes.getAlgorithm(), claimArray, jwtAttributes.getAudiences());
JWSSigner signer = new RSASSASigner(privateKey);
token.sign(signer);
return token;
}
- @Override
- public JWT issueToken(Principal p, String algorithm, long expiry) {
- return issueToken(p, Collections.emptyList(), algorithm, expiry);
- }
@Override
public boolean verifyToken(JWT token, RSAPublicKey publicKey) {
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
new file mode 100644
index 0000000..b6db56c
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributes.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.security.token;
+
+import java.security.Principal;
+import java.util.List;
+
+public class JWTokenAttributes {
+
+ private final Principal principal;
+ private final List<String> audiences;
+ private final String algorithm;
+ private final long expires;
+ private final String signingKeystoreName;
+ private final String signingKeystoreAlias;
+ private final char[] signingKeystorePassphrase;
+ private final boolean managed;
+
+ JWTokenAttributes(Principal principal, List<String> audiences, String algorithm, long expires, String signingKeystoreName, String signingKeystoreAlias,
+ char[] signingKeystorePassphrase, boolean managed) {
+ super();
+ this.principal = principal;
+ this.audiences = audiences;
+ this.algorithm = algorithm;
+ this.expires = expires;
+ this.signingKeystoreName = signingKeystoreName;
+ this.signingKeystoreAlias = signingKeystoreAlias;
+ this.signingKeystorePassphrase = signingKeystorePassphrase;
+ this.managed = managed;
+ }
+
+ public Principal getPrincipal() {
+ return principal;
+ }
+
+ public List<String> getAudiences() {
+ return audiences;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public long getExpires() {
+ return expires;
+ }
+
+ public String getSigningKeystoreName() {
+ return signingKeystoreName;
+ }
+
+ public String getSigningKeystoreAlias() {
+ return signingKeystoreAlias;
+ }
+
+ public char[] getSigningKeystorePassphrase() {
+ return signingKeystorePassphrase;
+ }
+
+ public boolean isManaged() {
+ return managed;
+ }
+
+}
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
new file mode 100644
index 0000000..c4028e4
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/JWTokenAttributesBuilder.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.security.token;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.List;
+
+import javax.security.auth.Subject;
+
+public class JWTokenAttributesBuilder {
+
+ private Principal principal;
+ private List<String> audiences;
+ private String algorithm;
+ private long expires;
+ private String signingKeystoreName;
+ private String signingKeystoreAlias;
+ private char[] signingKeystorePassphrase;
+ private boolean managed;
+
+ public JWTokenAttributesBuilder setPrincipal(Subject subject) {
+ return setPrincipal((Principal) subject.getPrincipals().toArray()[0]);
+ }
+
+ public JWTokenAttributesBuilder setPrincipal(Principal principal) {
+ this.principal = principal;
+ return this;
+ }
+
+ public JWTokenAttributesBuilder setAudiences(String audience) {
+ return setAudiences(Collections.singletonList(audience));
+ }
+
+ public JWTokenAttributesBuilder setAudiences(List<String> audiences) {
+ this.audiences = audiences;
+ return this;
+ }
+
+ public JWTokenAttributesBuilder setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ return this;
+ }
+
+ public JWTokenAttributesBuilder setExpires(long expires) {
+ this.expires = expires;
+ return this;
+ }
+
+ public JWTokenAttributesBuilder setSigningKeystoreName(String signingKeystoreName) {
+ this.signingKeystoreName = signingKeystoreName;
+ return this;
+ }
+
+ public JWTokenAttributesBuilder setSigningKeystoreAlias(String signingKeystoreAlias) {
+ this.signingKeystoreAlias = signingKeystoreAlias;
+ return this;
+ }
+
+ public JWTokenAttributesBuilder setSigningKeystorePassphrase(char[] signingKeystorePassphrase) {
+ this.signingKeystorePassphrase = signingKeystorePassphrase;
+ return this;
+ }
+
+ public JWTokenAttributesBuilder setManaged(boolean managed) {
+ this.managed = managed;
+ return this;
+ }
+
+ public JWTokenAttributes build() {
+ return new JWTokenAttributes(principal, (audiences == null ? Collections.emptyList() : audiences), algorithm, expires, signingKeystoreName, signingKeystoreAlias,
+ signingKeystorePassphrase, managed);
+ }
+
+}
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 5ba10d1..837cd11 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
@@ -17,40 +17,17 @@
*/
package org.apache.knox.gateway.services.security.token;
-import java.security.Principal;
import java.security.interfaces.RSAPublicKey;
-import java.util.List;
-
-import javax.security.auth.Subject;
import org.apache.knox.gateway.services.security.token.impl.JWT;
public interface JWTokenAuthority {
- JWT issueToken(Subject subject, String algorithm)
- throws TokenServiceException;
-
- JWT issueToken(Principal p, String algorithm)
- throws TokenServiceException;
-
- JWT issueToken(Principal p, String audience,
- String algorithm) throws TokenServiceException;
+ JWT issueToken(JWTokenAttributes jwtAttributes) throws TokenServiceException;
boolean verifyToken(JWT token) throws TokenServiceException;
boolean verifyToken(JWT token, RSAPublicKey publicKey) throws TokenServiceException;
- boolean verifyToken(JWT token, String jwksurl ,String algorithm ) throws TokenServiceException;
-
- JWT issueToken(Principal p, String algorithm, long expires) throws TokenServiceException;
-
- JWT issueToken(Principal p, String audience, String algorithm,
- long expires) throws TokenServiceException;
-
- JWT issueToken(Principal p, List<String> audiences, String algorithm,
- long expires) throws TokenServiceException;
-
- JWT issueToken(Principal p, List<String> audiences, String algorithm, long expires,
- String signingKeystoreName, String signingKeystoreAlias, char[] signingKeystorePassphrase)
- throws TokenServiceException;
+ boolean verifyToken(JWT token, String jwksurl, String algorithm) throws TokenServiceException;
}
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 b5be234..1b6d936 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
@@ -38,6 +38,7 @@ public class JWTToken implements JWT {
private static JWTProviderMessages log = MessagesFactory.get( JWTProviderMessages.class );
public static final String KNOX_ID_CLAIM = "knox.id";
+ public static final String MANAGED_TOKEN_CLAIM = "managed.token";
SignedJWT jwt;
@@ -59,6 +60,10 @@ public class JWTToken implements JWT {
}
public JWTToken(String alg, String[] claimsArray, List<String> audiences) {
+ this(alg, claimsArray, audiences, false);
+ }
+
+ public JWTToken(String alg, String[] claimsArray, List<String> audiences, boolean managed) {
JWSHeader header = new JWSHeader(new JWSAlgorithm(alg));
if (claimsArray[2] != null) {
@@ -79,6 +84,8 @@ public class JWTToken implements JWT {
// Add a private UUID claim for uniqueness
builder.claim(KNOX_ID_CLAIM, String.valueOf(UUID.randomUUID()));
+ builder.claim(MANAGED_TOKEN_CLAIM, String.valueOf(managed));
+
claims = builder.build();
jwt = new SignedJWT(header, claims);