KEYCLOAK-8481 Don't include empty resource_access in access token

This commit is contained in:
mposolda 2018-10-09 05:40:13 +02:00 committed by Stian Thorgersen
parent aaa33ad883
commit 5b51c000af
3 changed files with 38 additions and 3 deletions

View file

@ -24,6 +24,7 @@ import org.keycloak.representations.idm.authorization.Permission;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -123,7 +124,7 @@ public class AccessToken extends IDToken {
protected Access realmAccess; protected Access realmAccess;
@JsonProperty("resource_access") @JsonProperty("resource_access")
protected Map<String, Access> resourceAccess = new HashMap<String, Access>(); protected Map<String, Access> resourceAccess;
@JsonProperty("authorization") @JsonProperty("authorization")
protected Authorization authorization; protected Authorization authorization;
@ -134,8 +135,9 @@ public class AccessToken extends IDToken {
@JsonProperty("scope") @JsonProperty("scope")
protected String scope; protected String scope;
@JsonIgnore
public Map<String, Access> getResourceAccess() { public Map<String, Access> getResourceAccess() {
return resourceAccess; return resourceAccess == null ? Collections.<String, Access>emptyMap() : resourceAccess;
} }
public void setResourceAccess(Map<String, Access> resourceAccess) { public void setResourceAccess(Map<String, Access> resourceAccess) {
@ -172,10 +174,14 @@ public class AccessToken extends IDToken {
@JsonIgnore @JsonIgnore
public Access getResourceAccess(String resource) { public Access getResourceAccess(String resource) {
return resourceAccess.get(resource); return resourceAccess == null ? null : resourceAccess.get(resource);
} }
public Access addAccess(String service) { public Access addAccess(String service) {
if (resourceAccess == null) {
resourceAccess = new HashMap<>();
}
Access access = resourceAccess.get(service); Access access = resourceAccess.get(service);
if (access != null) return access; if (access != null) return access;
access = new Access(); access = new Access();

View file

@ -118,6 +118,27 @@ public class SkeletonKeyTokenTest {
ois.close(); ois.close();
} }
@Test
public void testTokenWithoutResourceAccess() throws Exception {
AccessToken token = new AccessToken();
token.id("111");
token.issuer("http://localhost:8080/auth/acme");
String json = JsonSerialization.writeValueAsString(token);
// Assert JSON doesn't contain "realm_access" or "resource_access" fields as it doesn't have any roles specified
Assert.assertFalse(json.contains("realm_access"));
Assert.assertFalse(json.contains("resource_access"));
token = JsonSerialization.readValue(json, AccessToken.class);
Assert.assertNull(token.getRealmAccess());
Assert.assertTrue(token.getResourceAccess() != null && token.getResourceAccess().isEmpty());
Assert.assertNull(token.getResourceAccess("foo"));
}
private AccessToken createSimpleToken() { private AccessToken createSimpleToken() {
AccessToken token = new AccessToken(); AccessToken token = new AccessToken();
token.id("111"); token.id("111");

View file

@ -27,6 +27,7 @@ import org.keycloak.admin.client.resource.ProtocolMappersResource;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource; import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.util.UriUtils; import org.keycloak.common.util.UriUtils;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.models.AccountRoles; import org.keycloak.models.AccountRoles;
import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory; import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
@ -50,6 +51,8 @@ import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.ProtocolMapperUtil; import org.keycloak.testsuite.util.ProtocolMapperUtil;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -402,6 +405,11 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
Assert.assertNull(accessToken.getRealmAccess()); Assert.assertNull(accessToken.getRealmAccess());
Assert.assertTrue(accessToken.getResourceAccess().isEmpty()); Assert.assertTrue(accessToken.getResourceAccess().isEmpty());
// KEYCLOAK-8481 Assert that accessToken JSON doesn't have "realm_access" or "resource_access" fields in it
String accessTokenJson = new String(new JWSInput(response.getAccessToken()).getContent(), StandardCharsets.UTF_8);
Assert.assertFalse(accessTokenJson.contains("realm_access"));
Assert.assertFalse(accessTokenJson.contains("resource_access"));
// Assert both realm and client roles on the new position. Hardcoded role should be here as well // Assert both realm and client roles on the new position. Hardcoded role should be here as well
Map<String, Object> cst1 = (Map<String, Object>) accessToken.getOtherClaims().get("custom"); Map<String, Object> cst1 = (Map<String, Object>) accessToken.getOtherClaims().get("custom");
List<String> roles = (List<String>) cst1.get("roles"); List<String> roles = (List<String>) cst1.get("roles");