diff --git a/docbook/reference/en/en-US/modules/proxy.xml b/docbook/reference/en/en-US/modules/proxy.xml
index 62848ec45d..f5f60536eb 100755
--- a/docbook/reference/en/en-US/modules/proxy.xml
+++ b/docbook/reference/en/en-US/modules/proxy.xml
@@ -274,4 +274,46 @@ $ java -jar bin/launcher.jar [your-config.json]
+
+ Keycloak Identity Headers
+
+ When forwarding requests to the proxied server, Keycloak Proxy will set some additional headers with values from the
+ OIDC identity token it received for authentication.
+
+
+ KEYCLOAK_SUBJECT
+
+
+ User id. Corresponds to JWT sub and will be the user id Keycloak uses to store
+ this user.
+
+
+
+
+ KEYCLOAK_USERNAME
+
+
+ Username. Corresponds to JWT preferred_username
+
+
+
+
+ KEYCLOAK_EMAIL
+
+
+ Email address of user if set.
+
+
+
+
+ KEYCLOAK_NAME
+
+
+ Full name of user if set.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1bf8595a03..08994f0bea 100755
--- a/pom.xml
+++ b/pom.xml
@@ -18,8 +18,8 @@
4.2.1
2.3.7.Final
3.0.9.Final
+
1.0.15.Final
-
2.7.0.CR2
1.0.2.Final
2.11.3
@@ -108,7 +108,7 @@
events
model
integration
- proxy
+ proxy/proxy-server
picketlink
federation
services
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 75b19e252f..d0ff18bcaf 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
@@ -2,7 +2,9 @@ package org.keycloak.proxy;
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.IDToken;
import java.util.Collection;
@@ -11,6 +13,10 @@ import java.util.Collection;
* @version $Revision: 1 $
*/
public class ConstraintAuthorizationHandler implements HttpHandler {
+ public static final HttpString KEYCLOAK_SUBJECT = new HttpString("KEYCLOAK_SUBJECT");
+ public static final HttpString KEYCLOAK_USERNAME = new HttpString("KEYCLOAK_USERNAME");
+ public static final HttpString KEYCLOAK_EMAIL = new HttpString("KEYCLOAK_EMAIL");
+ public static final HttpString KEYCLOAK_NAME = new HttpString("KEYCLOAK_NAME");
protected HttpHandler next;
protected String errorPage;
@@ -25,13 +31,13 @@ public class ConstraintAuthorizationHandler implements HttpHandler {
KeycloakUndertowAccount account = (KeycloakUndertowAccount)exchange.getSecurityContext().getAuthenticatedAccount();
SingleConstraintMatch match = exchange.getAttachment(ConstraintMatcherHandler.CONSTRAINT_KEY);
if (match == null || (match.getRequiredRoles().isEmpty() && match.getEmptyRoleSemantic() == SecurityInfo.EmptyRoleSemantic.AUTHENTICATE)) {
- next.handleRequest(exchange);
+ authenticatedRequest(account, exchange);
return;
}
if (match != null) {
for (String role : match.getRequiredRoles()) {
if (account.getRoles().contains(role)) {
- next.handleRequest(exchange);
+ authenticatedRequest(account, exchange);
return;
}
}
@@ -48,4 +54,23 @@ public class ConstraintAuthorizationHandler implements HttpHandler {
exchange.endExchange();
}
+
+ public void authenticatedRequest(KeycloakUndertowAccount account, HttpServerExchange exchange) throws Exception {
+ if (account != null) {
+ IDToken idToken = account.getKeycloakSecurityContext().getIdToken();
+ if (idToken.getSubject() != null) {
+ exchange.getRequestHeaders().put(KEYCLOAK_SUBJECT, idToken.getSubject());
+ }
+ if (idToken.getPreferredUsername() != null) {
+ exchange.getRequestHeaders().put(KEYCLOAK_USERNAME, idToken.getPreferredUsername());
+ }
+ if (idToken.getEmail() != null) {
+ exchange.getRequestHeaders().put(KEYCLOAK_EMAIL, idToken.getEmail());
+ }
+ if (idToken.getName() != null) {
+ exchange.getRequestHeaders().put(KEYCLOAK_NAME, idToken.getName());
+ }
+ }
+ next.handleRequest(exchange);
+ }
}
diff --git a/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java b/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java
index 0c27c20705..3c55b80aa3 100755
--- a/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java
+++ b/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java
@@ -70,6 +70,7 @@ import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.security.Principal;
+import java.util.Enumeration;
import java.util.regex.Matcher;
/**
@@ -100,8 +101,11 @@ public class ProxyTest {
req.getSession().setAttribute("counter", new Integer(count.intValue() + 1));
stream.write(("count:"+count).getBytes());
-
-
+ Enumeration headers = req.getHeaderNames();
+ while (headers.hasMoreElements()) {
+ String name = headers.nextElement();
+ System.out.println(name +": " + req.getHeader(name));
+ }
}
@Override
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {