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/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();