This is an automated email from the ASF dual-hosted git repository.
amagyar 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 8c468b095 KNOX-2732 Issuer claim in Knox JWTs should be configurable
(#560)
8c468b095 is described below
commit 8c468b095128ef9dd83e08d80e45a4c3db2ff44d
Author: Attila Magyar <[email protected]>
AuthorDate: Mon May 23 11:56:33 2022 +0200
KNOX-2732 Issuer claim in Knox JWTs should be configurable (#560)
---
.../jwt/filter/JWTAccessTokenAssertionFilter.java | 15 ++++++++-
.../jwt/filter/JWTAuthCodeAssertionFilter.java | 13 +++++++-
.../gateway/service/knoxsso/WebSSOResource.java | 18 ++++++++--
.../gateway/service/knoxtoken/TokenResource.java | 7 +++-
.../knoxtoken/TokenServiceResourceTest.java | 39 ++++++++++++++++++++++
.../services/security/token/JWTokenAttributes.java | 1 +
.../security/token/JWTokenAttributesBuilder.java | 2 +-
7 files changed, 89 insertions(+), 6 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 2bfcd9d34..fbcef111e 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
@@ -31,6 +31,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
import org.apache.knox.gateway.filter.security.AbstractIdentityAssertionFilter;
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
import org.apache.knox.gateway.provider.federation.jwt.JWTMessages;
@@ -51,10 +52,12 @@ public class JWTAccessTokenAssertionFilter extends
AbstractIdentityAssertionFilt
private static final String TOKEN_TYPE = "token_type";
private static final String ACCESS_TOKEN = "access_token";
private static final String BEARER = "Bearer ";
+ public static final String ISSUER = "knox.token.issuer";
private static JWTMessages log = MessagesFactory.get( JWTMessages.class );
private long validity;
private JWTokenAuthority authority;
private ServiceRegistry sr;
+ private String tokenIssuer;
@Override
public void init( FilterConfig filterConfig ) throws ServletException {
@@ -68,6 +71,10 @@ public class JWTAccessTokenAssertionFilter extends
AbstractIdentityAssertionFilt
GatewayServices services = (GatewayServices)
filterConfig.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
authority = services.getService(ServiceType.TOKEN_SERVICE);
sr = services.getService(ServiceType.SERVICE_REGISTRY_SERVICE);
+
+ this.tokenIssuer =
StringUtils.isBlank(filterConfig.getInitParameter(JWTAccessTokenAssertionFilter.ISSUER))
+ ? JWTokenAttributes.DEFAULT_ISSUER
+ :
filterConfig.getInitParameter(JWTAccessTokenAssertionFilter.ISSUER);
}
@Override
@@ -141,7 +148,13 @@ public class JWTAccessTokenAssertionFilter extends
AbstractIdentityAssertionFilt
JWT token;
try {
- final JWTokenAttributes jwtAttributes = new
JWTokenAttributesBuilder().setUserName(principalName).setAudiences(serviceName).setAlgorithm(signatureAlgorithm).setExpires(expires).build();
+ final JWTokenAttributes jwtAttributes = new JWTokenAttributesBuilder()
+ .setIssuer(tokenIssuer)
+ .setUserName(principalName)
+ .setAudiences(serviceName)
+ .setAlgorithm(signatureAlgorithm)
+ .setExpires(expires)
+ .build();
token = authority.issueToken(jwtAttributes);
// Coverity CID 1327961
if( token != null ) {
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 7bd3b553f..4589bfcae 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
@@ -28,10 +28,12 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import org.apache.commons.lang3.StringUtils;
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.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;
@@ -42,6 +44,7 @@ public class JWTAuthCodeAssertionFilter extends
AbstractIdentityAssertionFilter
private JWTokenAuthority authority;
private ServiceRegistry sr;
+ private String tokenIssuer;
@Override
public void init( FilterConfig filterConfig ) throws ServletException {
@@ -55,6 +58,10 @@ public class JWTAuthCodeAssertionFilter extends
AbstractIdentityAssertionFilter
GatewayServices services = (GatewayServices)
filterConfig.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
authority = services.getService(ServiceType.TOKEN_SERVICE);
sr = services.getService(ServiceType.SERVICE_REGISTRY_SERVICE);
+
+ this.tokenIssuer =
StringUtils.isBlank(filterConfig.getInitParameter(JWTAccessTokenAssertionFilter.ISSUER))
+ ? JWTokenAttributes.DEFAULT_ISSUER
+ :
filterConfig.getInitParameter(JWTAccessTokenAssertionFilter.ISSUER);
}
@Override
@@ -65,7 +72,11 @@ public class JWTAuthCodeAssertionFilter extends
AbstractIdentityAssertionFilter
principalName = mapper.mapUserPrincipal(principalName);
JWT authCode;
try {
- authCode = authority.issueToken(new
JWTokenAttributesBuilder().setUserName(principalName).setAlgorithm(signatureAlgorithm).build());
+ authCode = authority.issueToken(new JWTokenAttributesBuilder()
+ .setIssuer(tokenIssuer)
+ .setUserName(principalName)
+ .setAlgorithm(signatureAlgorithm)
+ .build());
// get the url for the token service
String url = null;
if (sr != null) {
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 522e3b94b..e48509a76 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
@@ -83,6 +83,7 @@ public class WebSSOResource {
private static final String SSO_SIGNINGKEY_KEYSTORE_NAME =
"knoxsso.signingkey.keystore.name";
private static final String SSO_SIGNINGKEY_KEYSTORE_ALIAS =
"knoxsso.signingkey.keystore.alias";
private static final String SSO_SIGNINGKEY_KEYSTORE_PASSPHRASE_ALIAS =
"knoxsso.signingkey.keystore.passphrase.alias";
+ private static final String SSO_TOKEN_ISSUER = "knoxsso.token.issuer";
/* parameters expected by knoxsso */
private static final String SSO_EXPECTED_PARAM = "knoxsso.expected.params";
@@ -104,6 +105,7 @@ public class WebSSOResource {
private String signatureAlgorithm;
private List<String> ssoExpectedparams = new ArrayList<>();
private String clusterName;
+ private String tokenIssuer;
@Context
HttpServletRequest request;
@@ -123,6 +125,10 @@ public class WebSSOResource {
String enableSessionStr =
context.getInitParameter(SSO_ENABLE_SESSION_PARAM);
this.enableSession = Boolean.parseBoolean(enableSessionStr);
+ this.tokenIssuer =
StringUtils.isBlank(context.getInitParameter(SSO_TOKEN_ISSUER))
+ ? JWTokenAttributes.DEFAULT_ISSUER
+ : context.getInitParameter(SSO_TOKEN_ISSUER);
+
setSignatureAlogrithm();
final String expectedParams = context.getInitParameter(SSO_EXPECTED_PARAM);
@@ -262,8 +268,16 @@ public class WebSSOResource {
signingKeystorePassphrase =
as.getPasswordFromAliasForCluster(clusterName, signingKeystorePassphraseAlias);
}
- final JWTokenAttributes jwtAttributes = new
JWTokenAttributesBuilder().setUserName(p.getName()).setAudiences(targetAudiences).setAlgorithm(signatureAlgorithm).setExpires(getExpiry())
-
.setSigningKeystoreName(signingKeystoreName).setSigningKeystoreAlias(signingKeystoreAlias).setSigningKeystorePassphrase(signingKeystorePassphrase).build();
+ final JWTokenAttributes jwtAttributes = new JWTokenAttributesBuilder()
+ .setIssuer(tokenIssuer)
+ .setUserName(p.getName())
+ .setAudiences(targetAudiences)
+ .setAlgorithm(signatureAlgorithm)
+ .setExpires(getExpiry())
+ .setSigningKeystoreName(signingKeystoreName)
+ .setSigningKeystoreAlias(signingKeystoreAlias)
+ .setSigningKeystorePassphrase(signingKeystorePassphrase)
+ .build();
JWT token = tokenAuthority.issueToken(jwtAttributes);
// Coverity CID 1327959
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 b0cc793e8..42fc815bc 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
@@ -148,7 +148,7 @@ public class TokenResource {
private static final String IMPERSONATION_ENABLED_PARAM = TOKEN_PARAM_PREFIX
+ "impersonation.enabled";
private static final String IMPERSONATION_ENABLED_TEXT =
"impersonationEnabled";
public static final String KNOX_TOKEN_INCLUDE_GROUPS = TOKEN_PARAM_PREFIX +
"include.groups";
-
+ public static final String KNOX_TOKEN_ISSUER = TOKEN_PARAM_PREFIX + "issuer";
private static TokenServiceMessages log =
MessagesFactory.get(TokenServiceMessages.class);
private long tokenTTL = TOKEN_TTL_DEFAULT;
private String tokenType;
@@ -172,6 +172,7 @@ public class TokenResource {
private int tokenLimitPerUser;
private boolean includeGroupsInTokenAllowed;
+ private String tokenIssuer;
enum UserLimitExceededAction {REMOVE_OLDEST, RETURN_ERROR};
private UserLimitExceededAction userLimitExceededAction =
UserLimitExceededAction.RETURN_ERROR;
@@ -245,6 +246,9 @@ public class TokenResource {
? true
: Boolean.parseBoolean(includeGroupsInTokenAllowedParam);
+ this.tokenIssuer =
StringUtils.isBlank(context.getInitParameter(KNOX_TOKEN_ISSUER))
+ ? JWTokenAttributes.DEFAULT_ISSUER
+ : context.getInitParameter(KNOX_TOKEN_ISSUER);
this.tokenType = context.getInitParameter(TOKEN_TYPE_PARAM);
tokenTTLAsText = getTokenTTLAsText();
@@ -768,6 +772,7 @@ public class TokenResource {
JWTokenAttributes jwtAttributes;
final JWTokenAttributesBuilder jwtAttributesBuilder = new
JWTokenAttributesBuilder();
jwtAttributesBuilder
+ .setIssuer(tokenIssuer)
.setUserName(userName)
.setAlgorithm(signatureAlgorithm)
.setExpires(expires)
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 6de3f2a2d..6812b195a 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
@@ -19,8 +19,10 @@ package org.apache.knox.gateway.service.knoxtoken;
import static
org.apache.knox.gateway.config.impl.GatewayConfigImpl.KNOX_TOKEN_USER_LIMIT;
import static
org.apache.knox.gateway.config.impl.GatewayConfigImpl.KNOX_TOKEN_USER_LIMIT_DEFAULT;
+import static
org.apache.knox.gateway.service.knoxtoken.TokenResource.KNOX_TOKEN_ISSUER;
import static
org.apache.knox.gateway.service.knoxtoken.TokenResource.KNOX_TOKEN_USER_LIMIT_EXCEEDED_ACTION;
import static
org.apache.knox.gateway.service.knoxtoken.TokenResource.TOKEN_INCLUDE_GROUPS_IN_JWT_ALLOWED;
+import static
org.apache.knox.gateway.services.security.token.JWTokenAttributes.DEFAULT_ISSUER;
import static
org.apache.knox.gateway.services.security.token.impl.JWTToken.KNOX_GROUPS_CLAIM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -1123,6 +1125,43 @@ public class TokenServiceResourceTest {
assertEquals(metadata.get("userName"), impersonatedUser);
}
+ @Test
+ public void testDefaultIssuer() throws Exception {
+ Map<String, String> contextExpectations = new HashMap<>();
+ configureCommonExpectations(contextExpectations, Boolean.TRUE);
+
+ TokenResource tr = new TokenResource();
+ tr.request = request;
+ tr.context = context;
+ tr.init();
+
+ Response response = tr.doGet();
+ assertEquals(200, response.getStatus());
+
+ String accessToken = getTagValue(response.getEntity().toString(),
"access_token");
+ Map<String, Object> payload =
parseJSONResponse(JWTToken.parseToken(accessToken).getPayload());
+ assertEquals(DEFAULT_ISSUER, payload.get("iss"));
+ }
+
+ @Test
+ public void testConfiguredIssuer() throws Exception {
+ Map<String, String> contextExpectations = new HashMap<>();
+ contextExpectations.put(KNOX_TOKEN_ISSUER, "test issuer");
+ configureCommonExpectations(contextExpectations, Boolean.TRUE);
+
+ TokenResource tr = new TokenResource();
+ tr.request = request;
+ tr.context = context;
+ tr.init();
+
+ Response response = tr.doGet();
+ assertEquals(200, response.getStatus());
+
+ String accessToken = getTagValue(response.getEntity().toString(),
"access_token");
+ Map<String, Object> payload =
parseJSONResponse(JWTToken.parseToken(accessToken).getPayload());
+ assertEquals("test issuer", payload.get("iss"));
+ }
+
@Test
public void testGroupsAddedToToken() throws Exception {
Set<String> groups = new HashSet<>(Arrays.asList("group1", "group2"));
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 a644c0a1f..8d3e4f067 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
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Set;
public class JWTokenAttributes {
+ public static final String DEFAULT_ISSUER = "KNOXSSO";
private final String userName;
private final List<String> audiences;
private final String algorithm;
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 4d86ff48a..6a63f34e8 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
@@ -36,7 +36,7 @@ public class JWTokenAttributesBuilder {
private String type;
private Set<String> groups;
private String kid;
- private String issuer = "KNOXSSO";
+ private String issuer = JWTokenAttributes.DEFAULT_ISSUER;
public JWTokenAttributesBuilder setUserName(String userName) {
this.userName = userName;