keycloak-uncached
Changes
examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java 16(+13 -3)
forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java 41(+41 -0)
Details
diff --git a/docbook/reference/en/en-US/modules/Overview.xml b/docbook/reference/en/en-US/modules/Overview.xml
index 3910cea..980c581 100755
--- a/docbook/reference/en/en-US/modules/Overview.xml
+++ b/docbook/reference/en/en-US/modules/Overview.xml
@@ -49,6 +49,9 @@
OAuth 2.0 Grant requests
</listitem>
<listitem>
+ OpenID Connect Support.
+ </listitem>
+ <listitem>
CORS Support
</listitem>
<listitem>
diff --git a/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java b/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
index 9ab51b2..f848909 100755
--- a/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
+++ b/examples/demo-template/third-party/src/main/java/org/keycloak/example/oauth/ProductDatabaseClient.java
@@ -5,6 +5,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.adapters.TokenGrantRequest;
+import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.servlet.ServletOAuthClient;
import org.keycloak.util.JsonSerialization;
@@ -50,7 +51,7 @@ public class ProductDatabaseClient {
static class TypedList extends ArrayList<String> {}
- public static List<String> getProducts(HttpServletRequest request) throws Failure {
+ public static AccessTokenResponse getTokenResponse(HttpServletRequest request) {
// The ServletOAuthClient is obtained by getting a context attribute
// that is set in the Bootstrap context listener in this project.
// You really should come up with a better way to initialize
@@ -59,17 +60,26 @@ public class ProductDatabaseClient {
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
String token = null;
try {
- token = oAuthClient.getBearerToken(request).getToken();
+ return oAuthClient.getBearerToken(request);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (TokenGrantRequest.HttpFailure failure) {
throw new RuntimeException(failure);
}
+ }
+
+ public static List<String> getProducts(HttpServletRequest request, String accessToken) throws Failure {
+ // The ServletOAuthClient is obtained by getting a context attribute
+ // that is set in the Bootstrap context listener in this project.
+ // You really should come up with a better way to initialize
+ // and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
+ // and take a look how it works. You can also take a look at third-party-cdi example
+ ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
HttpClient client = oAuthClient.getClient();
HttpGet get = new HttpGet("http://localhost:8080/database/products");
- get.addHeader("Authorization", "Bearer " + token);
+ get.addHeader("Authorization", "Bearer " + accessToken);
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != 200) {
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 0ccfbcb..6d998b7 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
@@ -1,4 +1,7 @@
<%@ page import="org.keycloak.example.oauth.ProductDatabaseClient" %>
+<%@ page import="org.keycloak.representations.AccessTokenResponse" %>
+<%@ page import="org.keycloak.representations.IDToken" %>
+<%@ page import="org.keycloak.servlet.ServletOAuthClient" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
@@ -6,17 +9,33 @@
<title>Pull Page</title>
</head>
<body>
-<h2>Pulled Product Listing</h2>
<%
java.util.List<String> list = null;
try {
- list = ProductDatabaseClient.getProducts(request);
+ AccessTokenResponse tokenResponse = ProductDatabaseClient.getTokenResponse(request);
+ if (tokenResponse.getIdToken() != null) {
+ IDToken idToken = ServletOAuthClient.extractIdToken(tokenResponse.getIdToken());
+ out.println("<p><i>Change client claims in admin console to view personal info of user</i></p>");
+ if (idToken.getPreferredUsername() != null) {
+ out.println("<p>Username: " + idToken.getPreferredUsername() + "</p>");
+ }
+ if (idToken.getName() != null) {
+ out.println("<p>Full Name: " + idToken.getName() + "</p>");
+ }
+ if (idToken.getEmail() != null) {
+ out.println("<p>Email: " + idToken.getEmail() + "</p>");
+ }
+ }
+ list = ProductDatabaseClient.getProducts(request, tokenResponse.getToken());
} catch (ProductDatabaseClient.Failure failure) {
out.println("There was a failure processing request. You either didn't configure Keycloak properly, or maybe" +
"you just forgot to secure the database service?");
out.println("Status from database service invocation was: " + failure.getStatus());
return;
}
+%>
+<h2>Pulled Product Listing</h2>
+<%
for (String prod : list)
{
out.print("<p>");
diff --git a/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl b/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl
index 5ca5a02..a44b2c7 100755
--- a/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl
+++ b/forms/common-themes/src/main/resources/theme/login/base/login-oauth-grant.ftl
@@ -9,6 +9,16 @@
<div id="kc-oauth" class="content-area">
<h3><strong>${oauth.client}</strong> ${rb.oauthGrantRequest}</h3>
<ul>
+ <#if oauth.claimsRequested??>
+ <li>
+ <span>
+ Personal Info:
+ <#list oauth.claimsRequested as claim>
+ ${claim}
+ </#list>
+ </span>
+ </li>
+ </#if>
<#list oauth.realmRolesRequested as role>
<li>
<span><#if role.description??>${role.description}<#else>${role.name}</#if></span>
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
index 94fdf8f..664b25b 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
@@ -21,12 +21,14 @@
*/
package org.keycloak.login.freemarker.model;
+import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import javax.ws.rs.core.MultivaluedMap;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
/**
@@ -38,6 +40,7 @@ public class OAuthGrantBean {
private MultivaluedMap<String, RoleModel> resourceRolesRequested;
private String code;
private ClientModel client;
+ private List<String> claimsRequested;
private String oAuthCode;
private String action;
@@ -46,6 +49,41 @@ public class OAuthGrantBean {
this.client = client;
this.realmRolesRequested = realmRolesRequested;
this.resourceRolesRequested = resourceRolesRequested;
+
+ // todo support locale
+ List<String> claims = new LinkedList<String>();
+ long mask = client.getAllowedClaimsMask();
+ if (ClaimMask.hasEmail(mask)) {
+ claims.add("email");
+ }
+ if (ClaimMask.hasUsername(mask)) {
+ claims.add("username");
+ }
+ if (ClaimMask.hasName(mask)) {
+ claims.add("name");
+ }
+ if (ClaimMask.hasGender(mask)) {
+ claims.add("gender");
+ }
+ if (ClaimMask.hasAddress(mask)) {
+ claims.add("address");
+ }
+ if (ClaimMask.hasPhone(mask)) {
+ claims.add("phone");
+ }
+ if (ClaimMask.hasPicture(mask)) {
+ claims.add("picture");
+ }
+ if (ClaimMask.hasProfile(mask)) {
+ claims.add("profile page");
+ }
+ if (ClaimMask.hasLocale(mask)) {
+ claims.add("locale");
+ }
+ if (ClaimMask.hasWebsite(mask)) {
+ claims.add("website");
+ }
+ if (claims.size() > 0) this.claimsRequested = claims;
}
public String getCode() {
@@ -64,4 +102,7 @@ public class OAuthGrantBean {
return client.getClientId();
}
+ public List<String> getClaimsRequested() {
+ return claimsRequested;
+ }
}
diff --git a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
index 44c0b9c..365d469 100755
--- a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
+++ b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
@@ -4,7 +4,9 @@ import org.apache.http.client.HttpClient;
import org.keycloak.AbstractOAuthClient;
import org.keycloak.adapters.HttpClientBuilder;
import org.keycloak.adapters.TokenGrantRequest;
+import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.IDToken;
import org.keycloak.util.KeycloakUriBuilder;
import javax.servlet.http.Cookie;
@@ -156,5 +158,15 @@ public class ServletOAuthClient extends AbstractOAuthClient {
return TokenGrantRequest.invokeRefresh(client, refreshToken, refreshUrl, clientId, credentials);
}
+ public static IDToken extractIdToken(String idToken) {
+ if (idToken == null) return null;
+ JWSInput input = new JWSInput(idToken);
+ try {
+ return input.readJsonContent(IDToken.class);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
index c8e7a84..7ed6f05 100755
--- a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
@@ -51,10 +51,7 @@ public class OAuthClientManager {
model.setSecret(rep.getSecret());
if (rep.getClaims() != null) {
ClaimManager.setClaims(model, rep.getClaims());
- } else {
- model.setAllowedClaimsMask(ClaimMask.USERNAME);
}
-
return model;
}