diff --git a/core/src/main/java/org/keycloak/representations/AccessToken.java b/core/src/main/java/org/keycloak/representations/AccessToken.java index efa736e446..eea0ed68bc 100755 --- a/core/src/main/java/org/keycloak/representations/AccessToken.java +++ b/core/src/main/java/org/keycloak/representations/AccessToken.java @@ -24,6 +24,7 @@ import org.keycloak.representations.idm.authorization.Permission; import java.io.Serializable; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -123,7 +124,7 @@ public class AccessToken extends IDToken { protected Access realmAccess; @JsonProperty("resource_access") - protected Map resourceAccess = new HashMap(); + protected Map resourceAccess; @JsonProperty("authorization") protected Authorization authorization; @@ -134,8 +135,9 @@ public class AccessToken extends IDToken { @JsonProperty("scope") protected String scope; + @JsonIgnore public Map getResourceAccess() { - return resourceAccess; + return resourceAccess == null ? Collections.emptyMap() : resourceAccess; } public void setResourceAccess(Map resourceAccess) { @@ -172,10 +174,14 @@ public class AccessToken extends IDToken { @JsonIgnore public Access getResourceAccess(String resource) { - return resourceAccess.get(resource); + return resourceAccess == null ? null : resourceAccess.get(resource); } public Access addAccess(String service) { + if (resourceAccess == null) { + resourceAccess = new HashMap<>(); + } + Access access = resourceAccess.get(service); if (access != null) return access; access = new Access(); diff --git a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java index ff11936325..38343333c8 100755 --- a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java +++ b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java @@ -118,6 +118,27 @@ public class SkeletonKeyTokenTest { 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() { AccessToken token = new AccessToken(); token.id("111"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java index 87f931e164..416a743090 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java @@ -27,6 +27,7 @@ import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.common.util.UriUtils; +import org.keycloak.jose.jws.JWSInput; import org.keycloak.models.AccountRoles; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory; @@ -50,6 +51,8 @@ import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.ProtocolMapperUtil; import javax.ws.rs.core.Response; + +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -402,6 +405,11 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest { Assert.assertNull(accessToken.getRealmAccess()); 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 Map cst1 = (Map) accessToken.getOtherClaims().get("custom"); List roles = (List) cst1.get("roles");