keycloak-developers

Merge pull request #1020 from patriot1burke/master ID Token

3/4/2015 10:42:21 PM

Changes

core/src/main/java/org/keycloak/representations/UserClaimSet.java 334(+0 -334)

Details

diff --git a/core/src/main/java/org/keycloak/representations/AddressClaimSet.java b/core/src/main/java/org/keycloak/representations/AddressClaimSet.java
new file mode 100755
index 0000000..4b47b8f
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/AddressClaimSet.java
@@ -0,0 +1,76 @@
+package org.keycloak.representations;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+* @version $Revision: 1 $
+*/
+public class AddressClaimSet {
+    @JsonProperty("formatted")
+    protected String formattedAddress;
+
+    @JsonProperty("street_address")
+    protected String streetAddress;
+
+    @JsonProperty("locality")
+    protected String locality;
+
+    @JsonProperty("region")
+    protected String region;
+
+    @JsonProperty("postal_code")
+    protected String postalCode;
+
+    @JsonProperty("country")
+    protected String country;
+
+    public String getFormattedAddress() {
+        return this.formattedAddress;
+    }
+
+    public void setFormattedAddress(String formattedAddress) {
+        this.formattedAddress = formattedAddress;
+    }
+
+    public String getStreetAddress() {
+        return this.streetAddress;
+    }
+
+    public void setStreetAddress(String streetAddress) {
+        this.streetAddress = streetAddress;
+    }
+
+    public String getLocality() {
+        return this.locality;
+    }
+
+    public void setLocality(String locality) {
+        this.locality = locality;
+    }
+
+    public String getRegion() {
+        return this.region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public String getPostalCode() {
+        return this.postalCode;
+    }
+
+    public void setPostalCode(String postalCode) {
+        this.postalCode = postalCode;
+    }
+
+    public String getCountry() {
+        return this.country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+}
diff --git a/core/src/main/java/org/keycloak/representations/IDToken.java b/core/src/main/java/org/keycloak/representations/IDToken.java
index fa58c9e..523d1f1 100755
--- a/core/src/main/java/org/keycloak/representations/IDToken.java
+++ b/core/src/main/java/org/keycloak/representations/IDToken.java
@@ -13,15 +13,73 @@ import java.util.Map;
  * @version $Revision: 1 $
  */
 public class IDToken extends JsonWebToken {
-
+    // NOTE!!!  WE used to use @JsonUnwrapped on a UserClaimSet object.  This screws up otherClaims and the won't work
+    // anymore.  So don't have any @JsonUnwrapped!
     @JsonProperty("nonce")
     protected String nonce;
 
     @JsonProperty("session_state")
     protected String sessionState;
 
-    @JsonUnwrapped
-    protected UserClaimSet userClaimSet = new UserClaimSet();
+    @JsonProperty("name")
+    protected String name;
+
+    @JsonProperty("given_name")
+    protected String givenName;
+
+    @JsonProperty("family_name")
+    protected String familyName;
+
+    @JsonProperty("middle_name")
+    protected String middleName;
+
+    @JsonProperty("nickname")
+    protected String nickName;
+
+    @JsonProperty("preferred_username")
+    protected String preferredUsername;
+
+    @JsonProperty("profile")
+    protected String profile;
+
+    @JsonProperty("picture")
+    protected String picture;
+
+    @JsonProperty("website")
+    protected String website;
+
+    @JsonProperty("email")
+    protected String email;
+
+    @JsonProperty("email_verified")
+    protected Boolean emailVerified;
+
+    @JsonProperty("gender")
+    protected String gender;
+
+    @JsonProperty("birthdate")
+    protected String birthdate;
+
+    @JsonProperty("zoneinfo")
+    protected String zoneinfo;
+
+    @JsonProperty("locale")
+    protected String locale;
+
+    @JsonProperty("phone_number")
+    protected String phoneNumber;
+
+    @JsonProperty("phone_number_verified")
+    protected Boolean phoneNumberVerified;
+
+    @JsonProperty("address")
+    protected AddressClaimSet address;
+
+    @JsonProperty("updated_at")
+    protected Long updatedAt;
+
+    @JsonProperty("claims_locales")
+    protected String claimsLocales;
 
     protected Map<String, Object> otherClaims = new HashMap<String, Object>();
 
@@ -41,17 +99,166 @@ public class IDToken extends JsonWebToken {
         this.sessionState = sessionState;
     }
 
-    /**
-     * Standardized OpenID Connect claims
-     *
-     * @return
-     */
-    public UserClaimSet getUserClaimSet() {
-        return this.userClaimSet;
+
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getGivenName() {
+        return this.givenName;
+    }
+
+    public void setGivenName(String givenName) {
+        this.givenName = givenName;
+    }
+
+    public String getFamilyName() {
+        return this.familyName;
+    }
+
+    public void setFamilyName(String familyName) {
+        this.familyName = familyName;
+    }
+
+    public String getMiddleName() {
+        return this.middleName;
+    }
+
+    public void setMiddleName(String middleName) {
+        this.middleName = middleName;
+    }
+
+    public String getNickName() {
+        return this.nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    public String getPreferredUsername() {
+        return this.preferredUsername;
+    }
+
+    public void setPreferredUsername(String preferredUsername) {
+        this.preferredUsername = preferredUsername;
+    }
+
+    public String getProfile() {
+        return this.profile;
+    }
+
+    public void setProfile(String profile) {
+        this.profile = profile;
+    }
+
+    public String getPicture() {
+        return this.picture;
+    }
+
+    public void setPicture(String picture) {
+        this.picture = picture;
+    }
+
+    public String getWebsite() {
+        return this.website;
+    }
+
+    public void setWebsite(String website) {
+        this.website = website;
+    }
+
+    public String getEmail() {
+        return this.email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public Boolean getEmailVerified() {
+        return this.emailVerified;
+    }
+
+    public void setEmailVerified(Boolean emailVerified) {
+        this.emailVerified = emailVerified;
+    }
+
+    public String getGender() {
+        return this.gender;
+    }
+
+    public void setGender(String gender) {
+        this.gender = gender;
+    }
+
+    public String getBirthdate() {
+        return this.birthdate;
+    }
+
+    public void setBirthdate(String birthdate) {
+        this.birthdate = birthdate;
+    }
+
+    public String getZoneinfo() {
+        return this.zoneinfo;
+    }
+
+    public void setZoneinfo(String zoneinfo) {
+        this.zoneinfo = zoneinfo;
+    }
+
+    public String getLocale() {
+        return this.locale;
+    }
+
+    public void setLocale(String locale) {
+        this.locale = locale;
+    }
+
+    public String getPhoneNumber() {
+        return this.phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public Boolean getPhoneNumberVerified() {
+        return this.phoneNumberVerified;
+    }
+
+    public void setPhoneNumberVerified(Boolean phoneNumberVerified) {
+        this.phoneNumberVerified = phoneNumberVerified;
+    }
+
+    public AddressClaimSet getAddress() {
+        return address;
+    }
+
+    public void setAddress(AddressClaimSet address) {
+        this.address = address;
+    }
+
+    public Long getUpdatedAt() {
+        return this.updatedAt;
+    }
+
+    public void setUpdatedAt(Long updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public String getClaimsLocales() {
+        return this.claimsLocales;
     }
 
-    public void setUserClaimSet(UserClaimSet userClaimSet) {
-        this.userClaimSet = userClaimSet;
+    public void setClaimsLocales(String claimsLocales) {
+        this.claimsLocales = claimsLocales;
     }
 
     /**
@@ -65,7 +272,7 @@ public class IDToken extends JsonWebToken {
     }
 
     @JsonAnySetter
-    public void setOtherClaims(Map<String, Object> otherClaims) {
-        this.otherClaims = otherClaims;
+    public void setOtherClaims(String name, Object value) {
+        otherClaims.put(name, value);
     }
 }
diff --git a/core/src/main/java/org/keycloak/representations/UserInfo.java b/core/src/main/java/org/keycloak/representations/UserInfo.java
old mode 100644
new mode 100755
index 3112981..d9542fa
--- a/core/src/main/java/org/keycloak/representations/UserInfo.java
+++ b/core/src/main/java/org/keycloak/representations/UserInfo.java
@@ -17,9 +17,248 @@
  */
 package org.keycloak.representations;
 
+import org.codehaus.jackson.annotate.JsonProperty;
+
 /**
  * @author pedroigor
  */
-public class UserInfo extends UserClaimSet {
+public class UserInfo {
+    @JsonProperty("sub")
+    protected String sub;
+
+    @JsonProperty("name")
+    protected String name;
+
+    @JsonProperty("given_name")
+    protected String givenName;
+
+    @JsonProperty("family_name")
+    protected String familyName;
+
+    @JsonProperty("middle_name")
+    protected String middleName;
+
+    @JsonProperty("nickname")
+    protected String nickName;
+
+    @JsonProperty("preferred_username")
+    protected String preferredUsername;
+
+    @JsonProperty("profile")
+    protected String profile;
+
+    @JsonProperty("picture")
+    protected String picture;
+
+    @JsonProperty("website")
+    protected String website;
+
+    @JsonProperty("email")
+    protected String email;
+
+    @JsonProperty("email_verified")
+    protected Boolean emailVerified;
+
+    @JsonProperty("gender")
+    protected String gender;
+
+    @JsonProperty("birthdate")
+    protected String birthdate;
+
+    @JsonProperty("zoneinfo")
+    protected String zoneinfo;
+
+    @JsonProperty("locale")
+    protected String locale;
+
+    @JsonProperty("phone_number")
+    protected String phoneNumber;
+
+    @JsonProperty("phone_number_verified")
+    protected Boolean phoneNumberVerified;
+
+    @JsonProperty("address")
+    protected AddressClaimSet address;
+
+    @JsonProperty("updated_at")
+    protected Long updatedAt;
+
+    @JsonProperty("claims_locales")
+    protected String claimsLocales;
+
+    public String getSubject() {
+        return this.sub;
+    }
+
+    public void setSubject(String subject) {
+        this.sub = subject;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getGivenName() {
+        return this.givenName;
+    }
+
+    public void setGivenName(String givenName) {
+        this.givenName = givenName;
+    }
+
+    public String getFamilyName() {
+        return this.familyName;
+    }
+
+    public void setFamilyName(String familyName) {
+        this.familyName = familyName;
+    }
+
+    public String getMiddleName() {
+        return this.middleName;
+    }
+
+    public void setMiddleName(String middleName) {
+        this.middleName = middleName;
+    }
+
+    public String getNickName() {
+        return this.nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    public String getPreferredUsername() {
+        return this.preferredUsername;
+    }
+
+    public void setPreferredUsername(String preferredUsername) {
+        this.preferredUsername = preferredUsername;
+    }
+
+    public String getProfile() {
+        return this.profile;
+    }
+
+    public void setProfile(String profile) {
+        this.profile = profile;
+    }
+
+    public String getPicture() {
+        return this.picture;
+    }
+
+    public void setPicture(String picture) {
+        this.picture = picture;
+    }
+
+    public String getWebsite() {
+        return this.website;
+    }
+
+    public void setWebsite(String website) {
+        this.website = website;
+    }
+
+    public String getEmail() {
+        return this.email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public Boolean getEmailVerified() {
+        return this.emailVerified;
+    }
+
+    public void setEmailVerified(Boolean emailVerified) {
+        this.emailVerified = emailVerified;
+    }
+
+    public String getGender() {
+        return this.gender;
+    }
+
+    public void setGender(String gender) {
+        this.gender = gender;
+    }
+
+    public String getBirthdate() {
+        return this.birthdate;
+    }
+
+    public void setBirthdate(String birthdate) {
+        this.birthdate = birthdate;
+    }
+
+    public String getZoneinfo() {
+        return this.zoneinfo;
+    }
+
+    public void setZoneinfo(String zoneinfo) {
+        this.zoneinfo = zoneinfo;
+    }
+
+    public String getLocale() {
+        return this.locale;
+    }
+
+    public void setLocale(String locale) {
+        this.locale = locale;
+    }
+
+    public String getPhoneNumber() {
+        return this.phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public Boolean getPhoneNumberVerified() {
+        return this.phoneNumberVerified;
+    }
+
+    public void setPhoneNumberVerified(Boolean phoneNumberVerified) {
+        this.phoneNumberVerified = phoneNumberVerified;
+    }
+
+    public AddressClaimSet getAddress() {
+        return address;
+    }
+
+    public void setAddress(AddressClaimSet address) {
+        this.address = address;
+    }
+
+    public Long getUpdatedAt() {
+        return this.updatedAt;
+    }
+
+    public void setUpdatedAt(Long updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public String getSub() {
+        return this.sub;
+    }
+
+    public void setSub(String sub) {
+        this.sub = sub;
+    }
+
+    public String getClaimsLocales() {
+        return this.claimsLocales;
+    }
 
+    public void setClaimsLocales(String claimsLocales) {
+        this.claimsLocales = claimsLocales;
+    }
 }
diff --git a/core/src/test/java/org/keycloak/JsonParserTest.java b/core/src/test/java/org/keycloak/JsonParserTest.java
index 7929495..1f51c21 100755
--- a/core/src/test/java/org/keycloak/JsonParserTest.java
+++ b/core/src/test/java/org/keycloak/JsonParserTest.java
@@ -26,6 +26,7 @@ public class JsonParserTest {
         IDToken test = new IDToken();
         test.getOtherClaims().put("phone_number", "978-666-0000");
         test.getOtherClaims().put("email_verified", "true");
+        test.getOtherClaims().put("yo", "true");
         Map<String, String> nested = new HashMap<String, String>();
         nested.put("foo", "bar");
         test.getOtherClaims().put("nested", nested);
@@ -33,11 +34,15 @@ public class JsonParserTest {
         System.out.println(json);
 
         test = JsonSerialization.readValue(json, IDToken.class);
-        System.out.println("email_verified property: " + test.getUserClaimSet().getEmailVerified());
-        System.out.println("property: " + test.getUserClaimSet().getPhoneNumber());
+        System.out.println("email_verified property: " + test.getEmailVerified());
+        System.out.println("property: " + test.getPhoneNumber());
         System.out.println("map: " + test.getOtherClaims().get("phone_number"));
-        Assert.assertNotNull(test.getUserClaimSet().getPhoneNumber());
+        Assert.assertNotNull(test.getPhoneNumber());
+        Assert.assertNotNull(test.getOtherClaims().get("yo"));
         Assert.assertNull(test.getOtherClaims().get("phone_number"));
+        nested = (Map<String, String>)test.getOtherClaims().get("nested");
+        Assert.assertNotNull(nested);
+        Assert.assertNotNull(nested.get("foo"));
     }
 
     @Test
diff --git a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
index e5a332d..268cddd 100755
--- a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
+++ b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
@@ -6,7 +6,6 @@ import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.crypto.RSAProvider;
 import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.UserClaimSet;
 import org.keycloak.representations.IDToken;
 import org.keycloak.util.JsonSerialization;
 
@@ -59,9 +58,8 @@ public class SkeletonKeyTokenTest {
     public void testSerialization() throws Exception {
         AccessToken token = createSimpleToken();
         IDToken idToken = new IDToken();
-        UserClaimSet claimSet = idToken.getUserClaimSet();
 
-        claimSet.setEmail("joe@email.cz");
+        idToken.setEmail("joe@email.cz");
 
         KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
 
@@ -98,7 +96,7 @@ public class SkeletonKeyTokenTest {
         Assert.assertEquals("111", token.getId());
         Assert.assertTrue(token.getResourceAccess("foo").isUserInRole("admin"));
         Assert.assertTrue(token.getResourceAccess("bar").isUserInRole("user"));
-        Assert.assertEquals("joe@email.cz", claimSet.getEmail());
+        Assert.assertEquals("joe@email.cz", idToken.getEmail());
         Assert.assertEquals("acme", ctx.getRealm());
         ois.close();
     }
diff --git a/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp b/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp
index 2eb5e66..04a54bb 100755
--- a/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp
+++ b/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp
@@ -3,7 +3,6 @@
 <%@ page import="org.keycloak.constants.ServiceUrlConstants" %>
 <%@ page import="org.keycloak.example.CustomerDatabaseClient" %>
 <%@ page import="org.keycloak.representations.IDToken" %>
-<%@ page import="org.keycloak.representations.UserClaimSet" %>
 <%@ page import="org.keycloak.util.KeycloakUriBuilder" %>
 <%@ page session="false" %>
 <html>
@@ -17,18 +16,17 @@
     String acctUri = KeycloakUriBuilder.fromUri("/auth").path(ServiceUrlConstants.ACCOUNT_SERVICE_PATH)
             .queryParam("referrer", "customer-portal").build("demo").toString();
     IDToken idToken = CustomerDatabaseClient.getIDToken(request);
-    UserClaimSet claims = idToken.getUserClaimSet();
 %>
 <p>Goto: <a href="/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a> | <a
         href="<%=acctUri%>">manage acct</a></p>
 Servlet User Principal <b><%=request.getUserPrincipal().getName()%>
 </b> made this request.
 <p><b>Caller IDToken values</b> (<i>You can specify what is returned in IDToken in the customer-portal claims page in the admin console</i>:</p>
-<p>Username: <%=claims.getPreferredUsername()%></p>
-<p>Email: <%=claims.getEmail()%></p>
-<p>Full Name: <%=claims.getName()%></p>
-<p>First: <%=claims.getGivenName()%></p>
-<p>Last: <%=claims.getFamilyName()%></p>
+<p>Username: <%=idToken.getPreferredUsername()%></p>
+<p>Email: <%=idToken.getEmail()%></p>
+<p>Full Name: <%=idToken.getName()%></p>
+<p>First: <%=idToken.getGivenName()%></p>
+<p>Last: <%=idToken.getFamilyName()%></p>
 <h2>Customer Listing</h2>
 <%
     java.util.List<String> list = null;
diff --git a/examples/demo-template/third-party/src/main/webapp/pull_data.jsp b/examples/demo-template/third-party/src/main/webapp/pull_data.jsp
index 6ed0478..9f102b4 100755
--- a/examples/demo-template/third-party/src/main/webapp/pull_data.jsp
+++ b/examples/demo-template/third-party/src/main/webapp/pull_data.jsp
@@ -2,7 +2,6 @@
 <%@ page import="org.keycloak.representations.AccessTokenResponse" %>
 <%@ page import="org.keycloak.representations.IDToken" %>
 <%@ page import="org.keycloak.servlet.ServletOAuthClient" %>
-<%@ page import="org.keycloak.representations.UserClaimSet" %>
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
 <%@ page session="false" %>
@@ -17,16 +16,15 @@
         AccessTokenResponse tokenResponse = ProductDatabaseClient.getTokenResponse(request);
         if (tokenResponse.getIdToken() != null) {
             IDToken idToken = ServletOAuthClient.extractIdToken(tokenResponse.getIdToken());
-            UserClaimSet claimSet = idToken.getUserClaimSet();
             out.println("<p><i>Change client claims in admin console to view personal info of user</i></p>");
-            if (claimSet.getPreferredUsername() != null) {
-                out.println("<p>Username: " + claimSet.getPreferredUsername() + "</p>");
+            if (idToken.getPreferredUsername() != null) {
+                out.println("<p>Username: " + idToken.getPreferredUsername() + "</p>");
             }
-            if (claimSet.getName() != null) {
-                out.println("<p>Full Name: " + claimSet.getName() + "</p>");
+            if (idToken.getName() != null) {
+                out.println("<p>Full Name: " + idToken.getName() + "</p>");
             }
-            if (claimSet.getEmail() != null) {
-                out.println("<p>Email: " + claimSet.getEmail() + "</p>");
+            if (idToken.getEmail() != null) {
+                out.println("<p>Email: " + idToken.getEmail() + "</p>");
             }
         }
         list = ProductDatabaseClient.getProducts(request, tokenResponse.getToken());
diff --git a/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java b/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
old mode 100644
new mode 100755
index ad41327..ff3237b
--- a/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
+++ b/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
@@ -55,7 +55,7 @@ public class ProtectedServlet extends HttpServlet {
         writer.write(principal.getKeycloakSecurityContext().getIdToken().getIssuer());
 
         writer.write("<br/>User: ");
-        writer.write(principal.getKeycloakSecurityContext().getIdToken().getUserClaimSet().getPreferredUsername());
+        writer.write(principal.getKeycloakSecurityContext().getIdToken().getPreferredUsername());
 
         writer.write(String.format("<br/><a href=\"/multitenant/%s/logout\">Logout</a>", realm));
     }
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterUtils.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterUtils.java
index 371696b..28b3d7d 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterUtils.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/AdapterUtils.java
@@ -4,7 +4,6 @@ import org.jboss.logging.Logger;
 import org.keycloak.KeycloakPrincipal;
 import org.keycloak.KeycloakSecurityContext;
 import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.UserClaimSet;
 import org.keycloak.util.UriUtils;
 
 import java.util.Collections;
@@ -78,22 +77,21 @@ public class AdapterUtils {
         String attr = "sub";
         if (deployment.getPrincipalAttribute() != null) attr = deployment.getPrincipalAttribute();
         String name = null;
-        UserClaimSet claimSet = token.getUserClaimSet();
 
         if ("sub".equals(attr)) {
             name = token.getSubject();
         } else if ("email".equals(attr)) {
-            name = claimSet.getEmail();
+            name = token.getEmail();
         } else if ("preferred_username".equals(attr)) {
-            name = claimSet.getPreferredUsername();
+            name = token.getPreferredUsername();
         } else if ("name".equals(attr)) {
-            name = claimSet.getName();
+            name = token.getName();
         } else if ("given_name".equals(attr)) {
-            name = claimSet.getGivenName();
+            name = token.getGivenName();
         } else if ("family_name".equals(attr)) {
-            name = claimSet.getFamilyName();
+            name = token.getFamilyName();
         } else if ("nickname".equals(attr)) {
-            name = claimSet.getNickName();
+            name = token.getNickName();
         }
         if (name == null) name = token.getSubject();
         return name;
diff --git a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintAuthorizationHandler.java b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintAuthorizationHandler.java
index add1404..58186dc 100755
--- a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintAuthorizationHandler.java
+++ b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ConstraintAuthorizationHandler.java
@@ -4,7 +4,6 @@ import io.undertow.server.HttpHandler;
 import io.undertow.server.HttpServerExchange;
 import io.undertow.util.HttpString;
 import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
-import org.keycloak.representations.UserClaimSet;
 import org.keycloak.representations.IDToken;
 
 /**
@@ -65,16 +64,14 @@ public class ConstraintAuthorizationHandler implements HttpHandler {
                 exchange.getRequestHeaders().put(KEYCLOAK_SUBJECT, idToken.getSubject());
             }
 
-            UserClaimSet claimSet = idToken.getUserClaimSet();
-
-            if (claimSet.getPreferredUsername() != null) {
-                exchange.getRequestHeaders().put(KEYCLOAK_USERNAME, claimSet.getPreferredUsername());
+            if (idToken.getPreferredUsername() != null) {
+                exchange.getRequestHeaders().put(KEYCLOAK_USERNAME, idToken.getPreferredUsername());
             }
-            if (claimSet.getEmail() != null) {
-                exchange.getRequestHeaders().put(KEYCLOAK_EMAIL, claimSet.getEmail());
+            if (idToken.getEmail() != null) {
+                exchange.getRequestHeaders().put(KEYCLOAK_EMAIL, idToken.getEmail());
             }
-            if (claimSet.getName() != null) {
-                exchange.getRequestHeaders().put(KEYCLOAK_NAME, claimSet.getName());
+            if (idToken.getName() != null) {
+                exchange.getRequestHeaders().put(KEYCLOAK_NAME, idToken.getName());
             }
             if (sendAccessToken) {
                 exchange.getRequestHeaders().put(KEYCLOAK_ACCESS_TOKEN, account.getKeycloakSecurityContext().getTokenString());
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddressMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddressMapper.java
index da7a258..235f2ab 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddressMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddressMapper.java
@@ -5,12 +5,15 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
 import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.AddressClaimSet;
 import org.keycloak.representations.IDToken;
-import org.keycloak.representations.UserClaimSet;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Set the 'name' claim to be first + last name.
@@ -42,6 +45,35 @@ public class OIDCAddressMapper extends AbstractOIDCProtocolMapper implements OID
 
     public static final String PROVIDER_ID = "oidc-address-mapper";
 
+    public static ProtocolMapperModel createAddressMapper() {
+        Map<String, String> config;
+        ProtocolMapperModel address = new ProtocolMapperModel();
+        address.setName("address");
+        address.setProtocolMapper(PROVIDER_ID);
+        address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+        address.setConsentRequired(true);
+        address.setConsentText("address");
+        config = new HashMap<String, String>();
+        config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
+        config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
+        address.setConfig(config);
+        return address;
+    }
+    public static ProtocolMapperModel createAddressMapper(boolean idToken, boolean accessToken) {
+        Map<String, String> config;
+        ProtocolMapperModel address = new ProtocolMapperModel();
+        address.setName("address");
+        address.setProtocolMapper(PROVIDER_ID);
+        address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+        address.setConsentRequired(true);
+        address.setConsentText("address");
+        config = new HashMap<String, String>();
+        config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, Boolean.toString(idToken));
+        config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, Boolean.toString(accessToken));
+        address.setConfig(config);
+        return address;
+    }
+
 
     public List<ConfigProperty> getConfigProperties() {
         return configProperties;
@@ -84,7 +116,7 @@ public class OIDCAddressMapper extends AbstractOIDCProtocolMapper implements OID
 
     protected void setClaim(IDToken token, UserSessionModel userSession) {
         UserModel user = userSession.getUser();
-        UserClaimSet.AddressClaimSet addressSet = new UserClaimSet.AddressClaimSet();
+        AddressClaimSet addressSet = new AddressClaimSet();
         addressSet.setStreetAddress(user.getAttribute("street"));
         addressSet.setLocality(user.getAttribute("locality"));
         addressSet.setRegion(user.getAttribute("region"));
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
index 2d58fea..1fc1277 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
@@ -7,7 +7,6 @@ import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.AbstractLoginProtocolFactory;
 import org.keycloak.protocol.LoginProtocol;
-import org.keycloak.protocol.ProtocolMapperUtils;
 import org.keycloak.protocol.oidc.mappers.OIDCAddressMapper;
 import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
 import org.keycloak.protocol.oidc.mappers.OIDCFullNameMapper;
@@ -88,16 +87,7 @@ public class OIDCLoginProtocolFactory extends AbstractLoginProtocolFactory {
         builtins.add(fullName);
         defaultBuiltins.add(fullName);
 
-        ProtocolMapperModel address = new ProtocolMapperModel();
-        address.setName("address");
-        address.setProtocolMapper(OIDCAddressMapper.PROVIDER_ID);
-        address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
-        address.setConsentRequired(true);
-        address.setConsentText("address");
-        config = new HashMap<String, String>();
-        config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
-        config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
-        address.setConfig(config);
+        ProtocolMapperModel address = OIDCAddressMapper.createAddressMapper();
         builtins.add(address);
     }
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
index 5e40809..5bcc031 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java
@@ -339,7 +339,7 @@ public class OIDCLoginProtocolService {
 
         TokenManager.attachClientSession(userSession, clientSession);
 
-        AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event)
+        AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event, session, userSession, clientSession)
                 .generateAccessToken(session, scope, client, user, userSession, clientSession)
                 .generateRefreshToken()
                 .generateIDToken()
@@ -506,9 +506,9 @@ public class OIDCLoginProtocolService {
             event.error(Errors.INVALID_TOKEN);
             return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
         }
-        AccessToken accessToken;
+        AccessTokenResponse res;
         try {
-            accessToken = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, event);
+            res = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, event);
         } catch (OAuthErrorException e) {
             Map<String, String> error = new HashMap<String, String>();
             error.put(OAuth2Constants.ERROR, e.getError());
@@ -517,10 +517,6 @@ public class OIDCLoginProtocolService {
             return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
         }
 
-        AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event)
-                .accessToken(accessToken)
-                .generateIDToken()
-                .generateRefreshToken().build();
 
         event.success();
 
@@ -680,7 +676,7 @@ public class OIDCLoginProtocolService {
             return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
         }
 
-        AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event)
+        AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event, session, userSession, clientSession)
                 .accessToken(token)
                 .generateIDToken()
                 .generateRefreshToken().build();
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index 55a78da..14fb6ec 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -22,6 +22,7 @@ import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.protocol.ProtocolMapper;
 import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
+import org.keycloak.protocol.oidc.mappers.OIDCIDTokenMapper;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.AccessTokenResponse;
 import org.keycloak.representations.IDToken;
@@ -58,7 +59,7 @@ public class TokenManager {
         }
     }
 
-    public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, EventBuilder event) throws OAuthErrorException {
+    public AccessTokenResponse refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, EventBuilder event) throws OAuthErrorException {
         RefreshToken refreshToken = verifyRefreshToken(realm, encodedRefreshToken);
 
         event.user(refreshToken.getSubject()).session(refreshToken.getSessionState()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId());
@@ -105,11 +106,15 @@ public class TokenManager {
         AccessToken accessToken = initToken(realm, client, user, userSession, clientSession);
         accessToken.setRealmAccess(refreshToken.getRealmAccess());
         accessToken.setResourceAccess(refreshToken.getResourceAccess());
-        accessToken = transformToken(session, accessToken, realm, client, user, userSession, clientSession);
+        accessToken = transformAccessToken(session, accessToken, realm, client, user, userSession, clientSession);
 
         userSession.setLastSessionRefresh(currentTime);
 
-        return accessToken;
+        AccessTokenResponse res = responseBuilder(realm, client, event, session, userSession, clientSession)
+                .accessToken(accessToken)
+                .generateIDToken()
+                .generateRefreshToken().build();
+        return res;
     }
 
     public RefreshToken verifyRefreshToken(RealmModel realm, String encodedRefreshToken) throws OAuthErrorException {
@@ -138,7 +143,7 @@ public class TokenManager {
         for (RoleModel role : requestedRoles) {
             addComposites(token, role);
         }
-        token = transformToken(session, token, realm, client, user, userSession, clientSession);
+        token = transformAccessToken(session, token, realm, client, user, userSession, clientSession);
         return token;
     }
 
@@ -233,8 +238,8 @@ public class TokenManager {
         }
     }
 
-    public AccessToken transformToken(KeycloakSession session, AccessToken token, RealmModel realm, ClientModel client, UserModel user,
-                                         UserSessionModel userSession, ClientSessionModel clientSession) {
+    public AccessToken transformAccessToken(KeycloakSession session, AccessToken token, RealmModel realm, ClientModel client, UserModel user,
+                                            UserSessionModel userSession, ClientSessionModel clientSession) {
         Set<ProtocolMapperModel> mappings = client.getProtocolMappers();
         KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
         for (ProtocolMapperModel mapping : mappings) {
@@ -249,6 +254,21 @@ public class TokenManager {
         }
         return token;
     }
+    public void transformIDToken(KeycloakSession session, IDToken token, RealmModel realm, ClientModel client, UserModel user,
+                                      UserSessionModel userSession, ClientSessionModel clientSession) {
+        Set<ProtocolMapperModel> mappings = client.getProtocolMappers();
+        KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
+        for (ProtocolMapperModel mapping : mappings) {
+            if (!mapping.getProtocol().equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) continue;
+
+            ProtocolMapper mapper = (ProtocolMapper)sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
+            if (mapper == null || !(mapper instanceof OIDCIDTokenMapper)) continue;
+            token = ((OIDCIDTokenMapper)mapper).transformIDToken(token, mapping, session, userSession, clientSession);
+
+
+
+        }
+    }
 
 
     protected AccessToken initToken(RealmModel realm, ClientModel client, UserModel user, UserSessionModel session, ClientSessionModel clientSession) {
@@ -308,22 +328,29 @@ public class TokenManager {
         return encodedToken;
     }
 
-    public AccessTokenResponseBuilder responseBuilder(RealmModel realm, ClientModel client, EventBuilder event) {
-        return new AccessTokenResponseBuilder(realm, client, event);
+    public AccessTokenResponseBuilder responseBuilder(RealmModel realm, ClientModel client, EventBuilder event, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
+        return new AccessTokenResponseBuilder(realm, client, event, session, userSession, clientSession);
     }
 
     public class AccessTokenResponseBuilder {
         RealmModel realm;
         ClientModel client;
+        EventBuilder event;
+        KeycloakSession session;
+        UserSessionModel userSession;
+        ClientSessionModel clientSession;
+
         AccessToken accessToken;
         RefreshToken refreshToken;
         IDToken idToken;
-        EventBuilder event;
 
-        public AccessTokenResponseBuilder(RealmModel realm, ClientModel client, EventBuilder event) {
+        public AccessTokenResponseBuilder(RealmModel realm, ClientModel client, EventBuilder event, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
             this.realm = realm;
             this.client = client;
             this.event = event;
+            this.session = session;
+            this.userSession = userSession;
+            this.clientSession = clientSession;
         }
 
         public AccessTokenResponseBuilder accessToken(AccessToken accessToken) {
@@ -366,25 +393,7 @@ public class TokenManager {
             if (realm.getAccessTokenLifespan() > 0) {
                 idToken.expiration(Time.currentTime() + realm.getAccessTokenLifespan());
             }
-            idToken.getUserClaimSet().setPreferredUsername(accessToken.getUserClaimSet().getPreferredUsername());
-            idToken.getUserClaimSet().setGivenName(accessToken.getUserClaimSet().getGivenName());
-            idToken.getUserClaimSet().setMiddleName(accessToken.getUserClaimSet().getMiddleName());
-            idToken.getUserClaimSet().setFamilyName(accessToken.getUserClaimSet().getFamilyName());
-            idToken.getUserClaimSet().setName(accessToken.getUserClaimSet().getName());
-            idToken.getUserClaimSet().setNickName(accessToken.getUserClaimSet().getNickName());
-            idToken.getUserClaimSet().setGender(accessToken.getUserClaimSet().getGender());
-            idToken.getUserClaimSet().setPicture(accessToken.getUserClaimSet().getPicture());
-            idToken.getUserClaimSet().setProfile(accessToken.getUserClaimSet().getProfile());
-            idToken.getUserClaimSet().setWebsite(accessToken.getUserClaimSet().getWebsite());
-            idToken.getUserClaimSet().setBirthdate(accessToken.getUserClaimSet().getBirthdate());
-            idToken.getUserClaimSet().setEmail(accessToken.getUserClaimSet().getEmail());
-            idToken.getUserClaimSet().setEmailVerified(accessToken.getUserClaimSet().getEmailVerified());
-            idToken.getUserClaimSet().setLocale(accessToken.getUserClaimSet().getLocale());
-            idToken.getUserClaimSet().setAddress(accessToken.getUserClaimSet().getAddress());
-            idToken.getUserClaimSet().setPhoneNumber(accessToken.getUserClaimSet().getPhoneNumber());
-            idToken.getUserClaimSet().setPhoneNumberVerified(accessToken.getUserClaimSet().getPhoneNumberVerified());
-            idToken.getUserClaimSet().setZoneinfo(accessToken.getUserClaimSet().getZoneinfo());
-            idToken.setOtherClaims(accessToken.getOtherClaims());
+            transformIDToken(session, idToken, realm, client, userSession.getUser(), userSession, clientSession);
             return this;
         }
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java b/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java
index c96b9f1..9958ae0 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/UserInfoService.java
@@ -31,7 +31,6 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.UserClaimSet;
 import org.keycloak.services.managers.AppAuthManager;
 import org.keycloak.services.managers.EventsManager;
 import org.keycloak.services.resources.Cors;
@@ -133,7 +132,7 @@ public class UserInfoService {
             ClientModel clientModel = realmModel.findClient(accessToken.getIssuedFor());
             UserModel userModel = userSession.getUser();
             AccessToken userInfo = new AccessToken();
-            this.tokenManager.transformToken(session, userInfo, realmModel, clientModel, userModel, userSession, null);
+            this.tokenManager.transformAccessToken(session, userInfo, realmModel, clientModel, userModel, userSession, null);
 
             event
                 .detail(Details.USERNAME, userModel.getUsername())
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/MultiTenantServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/MultiTenantServlet.java
old mode 100644
new mode 100755
index 1501f04..e464a7b
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/MultiTenantServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/MultiTenantServlet.java
@@ -38,7 +38,7 @@ public class MultiTenantServlet extends HttpServlet {
         KeycloakSecurityContext context = (KeycloakSecurityContext)req.getAttribute(KeycloakSecurityContext.class.getName());
 
         pw.print("Username: ");
-        pw.println(context.getIdToken().getUserClaimSet().getPreferredUsername());
+        pw.println(context.getIdToken().getPreferredUsername());
 
         pw.print("<br/>Realm: ");
         pw.println(context.getRealm());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index d03cb59..6fca683 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -26,18 +26,24 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
+import org.keycloak.VerificationException;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.Event;
+import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
+import org.keycloak.protocol.oidc.mappers.OIDCAddressMapper;
+import org.keycloak.protocol.oidc.mappers.OIDCUserAttributeMapper;
 import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.IDToken;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.AssertEvents;
 import org.keycloak.testsuite.OAuthClient;
@@ -58,6 +64,7 @@ import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
+import java.io.IOException;
 import java.net.URI;
 import java.util.HashMap;
 
@@ -570,6 +577,84 @@ public class AccessTokenTest {
 
     }
 
+    @Test
+    public void testTokenMapping() throws Exception {
+        Client client = ClientBuilder.newClient();
+        UriBuilder builder = UriBuilder.fromUri(org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT);
+        URI grantUri = OIDCLoginProtocolService.grantAccessTokenUrl(builder).build("test");
+        WebTarget grantTarget = client.target(grantUri);
+        {
+            KeycloakSession session = keycloakRule.startSession();
+            RealmModel realm = session.realms().getRealmByName("test");
+            UserModel user = session.users().getUserByUsername("test-user@localhost", realm);
+            user.setAttribute("street", "5 Yawkey Way");
+            user.setAttribute("locality", "Boston");
+            user.setAttribute("region", "MA");
+            user.setAttribute("postal_code", "02115");
+            user.setAttribute("country", "USA");
+            user.setAttribute("phone", "617-777-6666");
+            ApplicationModel app = realm.getApplicationByName("test-app");
+            ProtocolMapperModel mapper = OIDCAddressMapper.createAddressMapper(true, true);
+            app.addProtocolMapper(mapper);
+            app.addProtocolMapper(OIDCUserAttributeMapper.createClaimMapper("custom phone", "phone", "home_phone", "String", true, "", true, true));
+            session.getTransaction().commit();
+            session.close();
+        }
+
+        {
+            Response response = executeGrantAccessTokenRequest(grantTarget);
+            Assert.assertEquals(200, response.getStatus());
+            org.keycloak.representations.AccessTokenResponse tokenResponse = response.readEntity(org.keycloak.representations.AccessTokenResponse.class);
+            IDToken idToken = getIdToken(tokenResponse);
+            Assert.assertNotNull(idToken.getAddress());
+            Assert.assertEquals(idToken.getAddress().getStreetAddress(), "5 Yawkey Way");
+            Assert.assertEquals(idToken.getAddress().getLocality(), "Boston");
+            Assert.assertEquals(idToken.getAddress().getRegion(), "MA");
+            Assert.assertEquals(idToken.getAddress().getPostalCode(), "02115");
+            Assert.assertEquals(idToken.getAddress().getCountry(), "USA");
+            Assert.assertNotNull(idToken.getOtherClaims().get("home_phone"));
+            //Assert.assertEquals("617-777-6666", idToken.getOtherClaims().get("home_phone"));
+
+            AccessToken accessToken = getAccessToken(tokenResponse);
+            Assert.assertNotNull(accessToken.getAddress());
+            Assert.assertEquals(accessToken.getAddress().getStreetAddress(), "5 Yawkey Way");
+            Assert.assertEquals(accessToken.getAddress().getLocality(), "Boston");
+            Assert.assertEquals(accessToken.getAddress().getRegion(), "MA");
+            Assert.assertEquals(accessToken.getAddress().getPostalCode(), "02115");
+            Assert.assertEquals(accessToken.getAddress().getCountry(), "USA");
+            Assert.assertNotNull(accessToken.getOtherClaims().get("home_phone"));
+            Assert.assertEquals("617-777-6666", accessToken.getOtherClaims().get("home_phone"));
+
+
+            response.close();
+        }
+        client.close();
+        events.clear();
+
+    }
+
+    private IDToken getIdToken(org.keycloak.representations.AccessTokenResponse tokenResponse) throws VerificationException {
+        JWSInput input = new JWSInput(tokenResponse.getIdToken());
+        IDToken idToken = null;
+        try {
+            idToken = input.readJsonContent(IDToken.class);
+        } catch (IOException e) {
+            throw new VerificationException();
+        }
+        return idToken;
+    }
+
+    private AccessToken getAccessToken(org.keycloak.representations.AccessTokenResponse tokenResponse) throws VerificationException {
+        JWSInput input = new JWSInput(tokenResponse.getIdToken());
+        AccessToken idToken = null;
+        try {
+            idToken = input.readJsonContent(AccessToken.class);
+        } catch (IOException e) {
+            throw new VerificationException();
+        }
+        return idToken;
+    }
+
     protected Response executeGrantAccessTokenRequest(WebTarget grantTarget) {
         String header = BasicAuthHelper.createHeader("test-app", "password");
         Form form = new Form();