keycloak-aplcache
Changes
examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java 7(+7 -0)
integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java 5(+3 -2)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java 2(+1 -1)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java 2(+1 -1)
integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java 21(+21 -0)
integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java 2(+1 -1)
integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java 4(+2 -2)
Details
diff --git a/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java b/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java
index 658e19a..6593f2d 100755
--- a/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java
+++ b/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java
@@ -2,6 +2,7 @@ package org.keycloak;
import org.keycloak.adapters.ResourceMetadata;
import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.IDToken;
import java.io.Serializable;
@@ -12,14 +13,18 @@ import java.io.Serializable;
public class KeycloakAuthenticatedSession implements Serializable {
protected String tokenString;
protected AccessToken token;
+ protected IDToken idToken;
+ protected String idTokenString;
protected transient ResourceMetadata metadata;
public KeycloakAuthenticatedSession() {
}
- public KeycloakAuthenticatedSession(String tokenString, AccessToken token, ResourceMetadata metadata) {
+ public KeycloakAuthenticatedSession(String tokenString, AccessToken token, String idTokenString, IDToken idToken, ResourceMetadata metadata) {
this.tokenString = tokenString;
this.token = token;
+ this.idToken = idToken;
+ this.idTokenString = idTokenString;
this.metadata = metadata;
}
@@ -38,4 +43,12 @@ public class KeycloakAuthenticatedSession implements Serializable {
public void setMetadata(ResourceMetadata metadata) {
this.metadata = metadata;
}
+
+ public IDToken getIdToken() {
+ return idToken;
+ }
+
+ public String getIdTokenString() {
+ return idTokenString;
+ }
}
diff --git a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
index 196579d..16b6a96 100755
--- a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
+++ b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
@@ -6,6 +6,7 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakAuthenticatedSession;
import org.keycloak.adapters.HttpClientBuilder;
+import org.keycloak.representations.IDToken;
import org.keycloak.util.JsonSerialization;
import javax.servlet.http.HttpServletRequest;
@@ -35,6 +36,12 @@ public class CustomerDatabaseClient {
}
}
+ public static IDToken getIDToken(HttpServletRequest req) {
+ KeycloakAuthenticatedSession session = (KeycloakAuthenticatedSession) req.getAttribute(KeycloakAuthenticatedSession.class.getName());
+ return session.getIdToken();
+
+ }
+
public static List<String> getCustomers(HttpServletRequest req) throws Failure {
KeycloakAuthenticatedSession session = (KeycloakAuthenticatedSession) req.getAttribute(KeycloakAuthenticatedSession.class.getName());
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 0e9ab0e..f966321 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
@@ -2,6 +2,7 @@
pageEncoding="ISO-8859-1" %>
<%@ page import="org.keycloak.example.CustomerDatabaseClient" %>
<%@ page import="org.keycloak.util.KeycloakUriBuilder" %>
+<%@ page import="org.keycloak.representations.IDToken" %>
<html>
<head>
<title>Customer View Page</title>
@@ -11,11 +12,18 @@
String logoutUri = KeycloakUriBuilder.fromUri("http://localhost:8080/auth/rest/realms/demo/tokens/logout")
.queryParam("redirect_uri", "http://localhost:8080/customer-portal").build().toString();
String acctUri = "http://localhost:8080/auth/rest/realms/demo/account";
+ IDToken idToken = CustomerDatabaseClient.getIDToken(request);
%>
<p>Goto: <a href="http://localhost:8080/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a> | <a
href="<%=acctUri%>">manage acct</a></p>
-User <b><%=request.getUserPrincipal().getName()%>
+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: <%=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/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java
index 8716e0e..7e14a79 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java
@@ -7,6 +7,7 @@ import org.keycloak.adapters.config.RealmConfiguration;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
import org.jboss.logging.Logger;
+import org.keycloak.representations.IDToken;
import java.io.IOException;
@@ -24,8 +25,8 @@ public class RefreshableKeycloakSession extends KeycloakAuthenticatedSession {
public RefreshableKeycloakSession() {
}
- public RefreshableKeycloakSession(String tokenString, AccessToken token, ResourceMetadata metadata, RealmConfiguration realmConfiguration, String refreshToken) {
- super(tokenString, token, metadata);
+ public RefreshableKeycloakSession(String tokenString, AccessToken token, String idTokenString, IDToken idToken, ResourceMetadata metadata, RealmConfiguration realmConfiguration, String refreshToken) {
+ super(tokenString, token, idTokenString, idToken, metadata);
this.realmConfiguration = realmConfiguration;
this.refreshToken = refreshToken;
}
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
index 86933f0..93be4f4 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
@@ -106,7 +106,7 @@ public class CatalinaBearerTokenAuthenticator {
principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skeletonKeyPrincipal, roles);
request.setUserPrincipal(principal);
request.setAuthType("OAUTH_BEARER");
- KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, resourceMetadata);
+ KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, null, null, resourceMetadata);
request.setAttribute(KeycloakAuthenticatedSession.class.getName(), skSession);
return true;
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
index 430b3bd..b6e8af9 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
@@ -262,7 +262,7 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
Session session = request.getSessionInternal(true);
session.setPrincipal(principal);
session.setAuthType("OAUTH");
- KeycloakAuthenticatedSession skSession = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), resourceMetadata, realmConfiguration, oauth.getRefreshToken());
+ KeycloakAuthenticatedSession skSession = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), oauth.getIdTokenString(), oauth.getIdToken(), resourceMetadata, realmConfiguration, oauth.getRefreshToken());
session.setNote(KeycloakAuthenticatedSession.class.getName(), skSession);
String username = token.getSubject();
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
index 35cb609..1cec19f 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
@@ -5,8 +5,10 @@ import org.keycloak.RSATokenVerifier;
import org.keycloak.VerificationException;
import org.keycloak.adapters.TokenGrantRequest;
import org.keycloak.adapters.config.RealmConfiguration;
+import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.IDToken;
import org.keycloak.util.KeycloakUriBuilder;
import javax.servlet.http.Cookie;
@@ -28,6 +30,8 @@ public class ServletOAuthLogin {
protected RealmConfiguration realmInfo;
protected int redirectPort;
protected String tokenString;
+ protected String idTokenString;
+ protected IDToken idToken;
protected AccessToken token;
protected String refreshToken;
@@ -50,6 +54,14 @@ public class ServletOAuthLogin {
return refreshToken;
}
+ public String getIdTokenString() {
+ return idTokenString;
+ }
+
+ public IDToken getIdToken() {
+ return idToken;
+ }
+
public RealmConfiguration getRealmInfo() {
return realmInfo;
}
@@ -246,8 +258,17 @@ public class ServletOAuthLogin {
}
tokenString = tokenResponse.getToken();
+ idTokenString = tokenResponse.getIdToken();
try {
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata().getRealmKey(), realmInfo.getMetadata().getRealm());
+ if (idTokenString != null) {
+ JWSInput input = new JWSInput(idTokenString);
+ try {
+ idToken = input.readJsonContent(IDToken.class);
+ } catch (IOException e) {
+ throw new VerificationException();
+ }
+ }
log.debug("Token Verification succeeded!");
} catch (VerificationException e) {
log.error("failed verification of token");
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
index 6e22636..88d29c4 100755
--- a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
@@ -67,7 +67,7 @@ public class JaxrsBearerTokenFilter implements ContainerRequestFilter {
try {
AccessToken token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata.getRealmKey(), resourceMetadata.getRealm());
- KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, resourceMetadata);
+ KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, null, null, resourceMetadata);
ResteasyProviderFactory.pushContext(KeycloakAuthenticatedSession.class, skSession);
String callerPrincipal = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : null;
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java
index 5b9ef86..ffa9505 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java
@@ -94,7 +94,7 @@ public class KeycloakAuthenticationMechanism implements AuthenticationMechanism
protected void completeAuthentication(HttpServerExchange exchange, SecurityContext securityContext, OAuthAuthenticator oauth) {
final KeycloakPrincipal principal = new KeycloakPrincipal(oauth.getToken().getSubject(), null);
- RefreshableKeycloakSession session = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), resourceMetadata, realmConfig, oauth.getRefreshToken());
+ RefreshableKeycloakSession session = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), oauth.getIdTokenString(), oauth.getIdToken(), resourceMetadata, realmConfig, oauth.getRefreshToken());
KeycloakUndertowAccount account = new KeycloakUndertowAccount(principal, session, adapterConfig, resourceMetadata);
securityContext.authenticationComplete(account, "KEYCLOAK", true);
login(exchange, account);
@@ -107,7 +107,7 @@ public class KeycloakAuthenticationMechanism implements AuthenticationMechanism
protected void completeAuthentication(SecurityContext securityContext, BearerTokenAuthenticator bearer) {
final KeycloakPrincipal principal = new KeycloakPrincipal(bearer.getToken().getSubject(), bearer.getSurrogate());
- RefreshableKeycloakSession session = new RefreshableKeycloakSession(bearer.getTokenString(), bearer.getToken(), resourceMetadata, realmConfig, null);
+ RefreshableKeycloakSession session = new RefreshableKeycloakSession(bearer.getTokenString(), bearer.getToken(), null, null, resourceMetadata, realmConfig, null);
KeycloakUndertowAccount account = new KeycloakUndertowAccount(principal, session, adapterConfig, resourceMetadata);
securityContext.authenticationComplete(account, "KEYCLOAK", false);
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java
index d21e5d3..29bb28a 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java
@@ -12,8 +12,10 @@ import org.keycloak.RSATokenVerifier;
import org.keycloak.adapters.config.RealmConfiguration;
import org.keycloak.VerificationException;
import org.keycloak.adapters.TokenGrantRequest;
+import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.IDToken;
import org.keycloak.util.KeycloakUriBuilder;
import java.io.IOException;
@@ -31,6 +33,8 @@ public class OAuthAuthenticator {
protected RealmConfiguration realmInfo;
protected int sslRedirectPort;
protected String tokenString;
+ protected String idTokenString;
+ protected IDToken idToken;
protected AccessToken token;
protected HttpServerExchange exchange;
protected KeycloakChallenge challenge;
@@ -58,6 +62,22 @@ public class OAuthAuthenticator {
return refreshToken;
}
+ public String getIdTokenString() {
+ return idTokenString;
+ }
+
+ public void setIdTokenString(String idTokenString) {
+ this.idTokenString = idTokenString;
+ }
+
+ public IDToken getIdToken() {
+ return idToken;
+ }
+
+ public void setIdToken(IDToken idToken) {
+ this.idToken = idToken;
+ }
+
protected String getRequestUrl() {
KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(exchange.getRequestURI())
.replaceQuery(exchange.getQueryString());
@@ -255,8 +275,17 @@ public class OAuthAuthenticator {
tokenString = tokenResponse.getToken();
refreshToken = tokenResponse.getRefreshToken();
+ idTokenString = tokenResponse.getIdToken();
try {
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata().getRealmKey(), realmInfo.getMetadata().getRealm());
+ if (idTokenString != null) {
+ JWSInput input = new JWSInput(idTokenString);
+ try {
+ idToken = input.readJsonContent(IDToken.class);
+ } catch (IOException e) {
+ throw new VerificationException();
+ }
+ }
log.debug("Token Verification succeeded!");
} catch (VerificationException e) {
log.error("failed verification of token");
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index 080d52f..8b4e8a6 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -6,6 +6,8 @@ import org.keycloak.jose.jws.JWSBuilder;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClaimMask;
+import org.keycloak.models.ClaimRequesterModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
@@ -13,7 +15,9 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessScope;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.IDToken;
import org.keycloak.representations.RefreshToken;
+import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.util.Base64Url;
import org.keycloak.util.JsonSerialization;
@@ -178,7 +182,9 @@ public class TokenManager {
}
}
- AccessToken accessToken = initToken(realm, client, user);
+ ClaimRequesterModel claimRequesterModel = getClaimRequester(realm, client);
+
+ AccessToken accessToken = initToken(realm, claimRequesterModel, client, user);
accessToken.setRealmAccess(refreshToken.getRealmAccess());
accessToken.setResourceAccess(refreshToken.getResourceAccess());
return accessToken;
@@ -188,6 +194,12 @@ public class TokenManager {
return createClientAccessToken(scopeParam, realm, client, user, new LinkedList<RoleModel>(), new MultivaluedHashMap<String, RoleModel>());
}
+ protected ClaimRequesterModel getClaimRequester(RealmModel realm, UserModel client) {
+ ClaimRequesterModel model = realm.getApplicationByName(client.getLoginName());
+ if (model != null) return model;
+ return realm.getOAuthClient(client.getLoginName());
+ }
+
public AccessToken createClientAccessToken(String scopeParam, RealmModel realm, UserModel client, UserModel user, List<RoleModel> realmRolesRequested, MultivaluedMap<String, RoleModel> resourceRolesRequested) {
AccessScope scopeMap = null;
@@ -196,6 +208,7 @@ public class TokenManager {
Set<RoleModel> roleMappings = realm.getRoleMappings(user);
Set<RoleModel> scopeMappings = realm.getScopeMappings(client);
+ ClaimRequesterModel claimRequesterModel = getClaimRequester(realm, client);
ApplicationModel clientApp = realm.getApplicationByName(client.getLoginName());
Set<RoleModel> clientAppRoles = clientApp == null ? null : clientApp.getRoles();
if (clientAppRoles != null) scopeMappings.addAll(clientAppRoles);
@@ -222,7 +235,7 @@ public class TokenManager {
}
}
- AccessToken token = initToken(realm, client, user);
+ AccessToken token = initToken(realm, claimRequesterModel, client, user);
if (realmRolesRequested.size() > 0) {
for (RoleModel role : realmRolesRequested) {
@@ -240,7 +253,42 @@ public class TokenManager {
return token;
}
- protected AccessToken initToken(RealmModel realm, UserModel client, UserModel user) {
+ public void initClaims(IDToken token, ClaimRequesterModel model, UserModel user) {
+ if (ClaimMask.hasUsername(model.getAllowedClaimsMask())) {
+ token.setPreferredUsername(user.getLoginName());
+ }
+ if (ClaimMask.hasEmail(model.getAllowedClaimsMask())) {
+ token.setEmail(user.getEmail());
+ token.setEmailVerified(user.isEmailVerified());
+ }
+ if (ClaimMask.hasName(model.getAllowedClaimsMask())) {
+ token.setFamilyName(user.getLastName());
+ token.setGivenName(user.getFirstName());
+ StringBuilder fullName = new StringBuilder();
+ if (user.getFirstName() != null) fullName.append(user.getFirstName()).append(" ");
+ if (user.getLastName() != null) fullName.append(user.getLastName());
+ token.setName(fullName.toString());
+ }
+ }
+
+ protected IDToken initIDToken(RealmModel realm, ClaimRequesterModel claimer, UserModel client, UserModel user) {
+ IDToken token = new IDToken();
+ token.id(KeycloakModelUtils.generateId());
+ token.subject(user.getId());
+ token.audience(realm.getName());
+ token.issuedNow();
+ token.issuedFor(client.getLoginName());
+ token.issuer(realm.getName());
+ if (realm.getAccessTokenLifespan() > 0) {
+ token.expiration((System.currentTimeMillis() / 1000) + realm.getAccessTokenLifespan());
+ }
+ initClaims(token, claimer, user);
+ return token;
+ }
+
+
+
+ protected AccessToken initToken(RealmModel realm, ClaimRequesterModel claimer, UserModel client, UserModel user) {
AccessToken token = new AccessToken();
token.id(KeycloakModelUtils.generateId());
token.subject(user.getId());
@@ -250,12 +298,12 @@ public class TokenManager {
token.issuer(realm.getName());
if (realm.getAccessTokenLifespan() > 0) {
token.expiration((System.currentTimeMillis() / 1000) + realm.getAccessTokenLifespan());
- logger.info("Access Token expiration: " + token.getExpiration());
}
Set<String> allowedOrigins = client.getWebOrigins();
if (allowedOrigins != null) {
token.setAllowedOrigins(allowedOrigins);
}
+ initClaims(token, claimer, user);
return token;
}
@@ -324,6 +372,7 @@ public class TokenManager {
RealmModel realm;
AccessToken accessToken;
RefreshToken refreshToken;
+ IDToken idToken;
public AccessTokenResponseBuilder(RealmModel realm) {
this.realm = realm;
@@ -354,8 +403,53 @@ public class TokenManager {
return this;
}
+ public AccessTokenResponseBuilder generateIDToken() {
+ if (accessToken == null) {
+ throw new IllegalStateException("accessToken not set");
+ }
+ idToken = new IDToken();
+ idToken.id(KeycloakModelUtils.generateId());
+ idToken.subject(accessToken.getSubject());
+ idToken.audience(realm.getName());
+ idToken.issuedNow();
+ idToken.issuedFor(accessToken.getIssuedFor());
+ idToken.issuer(accessToken.getIssuer());
+ if (realm.getAccessTokenLifespan() > 0) {
+ idToken.expiration((System.currentTimeMillis() / 1000) + realm.getAccessTokenLifespan());
+ }
+ idToken.setPreferredUsername(accessToken.getPreferredUsername());
+ idToken.setGivenName(accessToken.getGivenName());
+ idToken.setMiddleName(accessToken.getMiddleName());
+ idToken.setFamilyName(accessToken.getFamilyName());
+ idToken.setName(accessToken.getName());
+ idToken.setNickName(accessToken.getNickName());
+ idToken.setGender(accessToken.getGender());
+ idToken.setPicture(accessToken.getPicture());
+ idToken.setProfile(accessToken.getProfile());
+ idToken.setWebsite(accessToken.getWebsite());
+ idToken.setBirthdate(accessToken.getBirthdate());
+ idToken.setEmail(accessToken.getEmail());
+ idToken.setEmailVerified(accessToken.getEmailVerified());
+ idToken.setLocale(accessToken.getLocale());
+ idToken.setFormattedAddress(accessToken.getFormattedAddress());
+ idToken.setAddress(accessToken.getAddress());
+ idToken.setStreetAddress(accessToken.getStreetAddress());
+ idToken.setLocality(accessToken.getLocality());
+ idToken.setRegion(accessToken.getRegion());
+ idToken.setPostalCode(accessToken.getPostalCode());
+ idToken.setCountry(accessToken.getCountry());
+ idToken.setPhoneNumber(accessToken.getPhoneNumber());
+ idToken.setPhoneNumberVerified(accessToken.getPhoneNumberVerified());
+ idToken.setZoneinfo(accessToken.getZoneinfo());
+ return this;
+ }
+
public AccessTokenResponse build() {
AccessTokenResponse res = new AccessTokenResponse();
+ if (idToken != null) {
+ String encodedToken = new JWSBuilder().jsonContent(idToken).rsa256(realm.getPrivateKey());
+ res.setIdToken(encodedToken);
+ }
if (accessToken != null) {
String encodedToken = new JWSBuilder().jsonContent(accessToken).rsa256(realm.getPrivateKey());
res.setToken(encodedToken);
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 44ac6e2..ba6ce97 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -159,7 +159,9 @@ public class TokenService {
}
String scope = form.getFirst("scope");
AccessTokenResponse res = tokenManager.responseBuilder(realm)
- .generateAccessToken(scope, client, user).build();
+ .generateAccessToken(scope, client, user)
+ .generateIDToken()
+ .build();
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
}
@@ -188,6 +190,7 @@ public class TokenService {
AccessTokenResponse res = tokenManager.responseBuilder(realm)
.accessToken(accessToken)
+ .generateIDToken()
.generateRefreshToken().build();
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
}
@@ -410,6 +413,7 @@ public class TokenService {
logger.debug("accessRequest SUCCESS");
AccessTokenResponse res = tokenManager.responseBuilder(realm)
.accessToken(accessCode.getToken())
+ .generateIDToken()
.generateRefreshToken().build();
return Cors.add(request, Response.ok(res)).allowedOrigins(client).allowedMethods("POST").build();