Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
Expand All @@ -51,6 +52,7 @@
import org.apache.knox.gateway.audit.log4j.audit.Log4jAuditor;
import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
import org.apache.knox.gateway.security.SubjectUtils;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.security.AliasService;
Expand Down Expand Up @@ -84,6 +86,7 @@ public class WebSSOResource {
private static final String SSO_COOKIE_TOKEN_TYPE_PARAM = "knoxsso.token.type";
private static final String SSO_COOKIE_TOKEN_AUDIENCES_PARAM = "knoxsso.token.audiences";
private static final String SSO_COOKIE_TOKEN_SIG_ALG = "knoxsso.token.sigalg";
private static final String SSO_COOKIE_INCLUDE_GROUPS_PARAM = "knoxsso.token.include.groups";
private static final String SSO_COOKIE_TOKEN_WHITELIST_PARAM = "knoxsso.redirect.whitelist.regex";

private static final String SSO_SIGNINGKEY_KEYSTORE_NAME = "knoxsso.signingkey.keystore.name";
Expand Down Expand Up @@ -111,6 +114,7 @@ public class WebSSOResource {
private List<String> targetAudiences = new ArrayList<>();
private boolean enableSession;
private String signatureAlgorithm;
private boolean includeGroups;
private List<String> ssoExpectedparams = new ArrayList<>();
private String clusterName;
private String tokenIssuer;
Expand Down Expand Up @@ -224,6 +228,8 @@ private void handleCookieSetup() {
}
final String configuredTokenType = context.getInitParameter(SSO_COOKIE_TOKEN_TYPE_PARAM);
tokenType = StringUtils.isBlank(configuredTokenType) ? JOSEObjectType.JWT.getType() : configuredTokenType;

includeGroups = Boolean.parseBoolean(context.getInitParameter(SSO_COOKIE_INCLUDE_GROUPS_PARAM));
Comment thread
moresandeep marked this conversation as resolved.
}

@GET
Expand Down Expand Up @@ -314,7 +320,9 @@ private Response getAuthenticationToken(int statusCode) {
.setSigningKeystorePassphrase(signingKeystorePassphrase)
.setManaged(tokenStateService != null)
.setType(tokenType)
.setGroups(groups())
.build();

JWT token = tokenAuthority.issueToken(jwtAttributes);

// Coverity CID 1327959
Expand Down Expand Up @@ -349,11 +357,13 @@ private Response getAuthenticationToken(int statusCode) {
// todo log return error response
}



return Response.seeOther(location).entity("{ \"redirectTo\" : " + original + " }").build();
}

Set<String> groups() {
return includeGroups ? SubjectUtils.getCurrentGroupPrincipalNames() : null;
}

protected String getOriginalUrlFromQueryParams() {
String original = request.getParameter(ORIGINAL_URL_REQUEST_PARAM);
StringBuilder buf = new StringBuilder(original);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,55 @@ public void testCustomSigningKey() throws Exception {
assertTrue(authority.verifyToken(parsedToken, customPublicKey));
}

@Test
public void testIncludeGroupsTrue() throws Exception {
testIncludeGroups(Boolean.TRUE, Collections.singleton("group1"), true);
}

@Test
public void testIncludeGroupsFalse() throws Exception {
testIncludeGroups(Boolean.FALSE, Collections.singleton("group1"), false);
}

@Test
public void testIncludeGroupsOmitted() throws Exception {
testIncludeGroups(null, Collections.singleton("group1"), false);
}

private void testIncludeGroups(Boolean includeGroupsParam, Set<String> groupsToReturn, boolean expectedInToken) throws Exception {
final boolean includeGroups = includeGroupsParam != null && includeGroupsParam;
configureCommonExpectations(includeGroups ? Map.of("knoxsso.token.include.groups", includeGroupsParam.toString()) : Map.of());

final TestWebSSOResource webSSOResponse = new TestWebSSOResource(includeGroups ? groupsToReturn : null);
webSSOResponse.request = request;
webSSOResponse.response = responseWrapper;
webSSOResponse.context = context;
webSSOResponse.init();

// Issue a token
webSSOResponse.doGet();

// Check the cookie
final Cookie cookie = responseWrapper.getCookie("hadoop-jwt");
assertNotNull(cookie);

final JWT parsedToken = new JWTToken(cookie.getValue());
assertEquals("alice", parsedToken.getSubject());
assertTrue(authority.verifyToken(parsedToken));

// Verify the groups
List<String> tokenGroups = (List<String>) parsedToken.getClaimAsObject(JWTToken.KNOX_GROUPS_CLAIM);
if (expectedInToken) {
assertNotNull(tokenGroups);
assertEquals(groupsToReturn.size(), tokenGroups.size());
for (String group : groupsToReturn) {
assertTrue(tokenGroups.contains(group));
}
} else {
Assert.assertNull(tokenGroups);
}
}

@Test
public void testConcurrentSessionLimitHit() throws Exception {
configureCommonExpectations(Collections.emptyMap(), false, false, false);
Expand Down Expand Up @@ -809,6 +858,24 @@ public void testGetOriginalUrlFromQueryParams() throws Exception {
}


private static class TestWebSSOResource extends WebSSOResource {
private final Set<String> groups;

private TestWebSSOResource(Set<String> groups) {
this.groups = groups;
}


@Override
Set<String> groups() {
try {
return groups;
} catch (Exception e) {
return null;
}
}
}

/**
* A wrapper for HttpServletResponseWrapper to store the cookies
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1149,11 +1149,7 @@ private boolean shouldIncludeGroups() {
}

protected Set<String> groups() {
Subject subject = SubjectUtils.getCurrentSubject();
Set<String> groups = subject.getPrincipals(GroupPrincipal.class).stream()
.map(GroupPrincipal::getName)
.collect(Collectors.toSet());
return groups;
return SubjectUtils.getCurrentGroupPrincipalNames();
}

protected void addArbitraryTokenMetadata(TokenMetadata tokenMetadata) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
* General utility methods for interrogating the standard java Subject
Expand Down Expand Up @@ -94,6 +95,11 @@ public static Set<GroupPrincipal> getCurrentGroupPrincipals() {
return subject == null ? Collections.emptySet() : getGroupPrincipals(subject);
}

public static Set<String> getCurrentGroupPrincipalNames() {
final Set<GroupPrincipal> groupPrincipals = getCurrentGroupPrincipals();
return groupPrincipals.isEmpty() ? Collections.emptySet() : groupPrincipals.stream().map(Principal::getName).collect(Collectors.toSet());
}

public static Set<GroupPrincipal> getGroupPrincipals(Subject subject) {
return subject.getPrincipals(GroupPrincipal.class);
}
Expand Down
Loading