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 {