Allow getting displayName/e-mail with auth.type=HTTP
When using HTTP-based authentication, the SSO can be
delegated to check not only the user credentials
but also to fetch the full user-profile (e.g. SiteMinder does).
With the config properties auth.httpDisplaynameHeader
and auth.httpEmailHeader it is possible to configure
the name of the headers used for propagating this
extra information and enforce them on the user profile
during login and beyond. This allows the company to
take full control of the user profile through a unique
entry point using HTTP authentication.
This is particularly useful if we consider all the
existing authentication mechanisms available with
an HTTP front-end reverse proxy:
- Kerberos
- Radius
- Generic SQL Database
- SiteMinder
- OAuth
Change-Id: I12f9cc0386acd11c03eeaa7475e4e9e8ab94a555
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 7dc70d2..e49ff77 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -255,6 +255,24 @@
HTTP header to trust the username from, or unset to select HTTP basic
or digest authentication. Only used if `auth.type` is set to `HTTP`.
+[[auth.httpDisplaynameHeader]]auth.httpDisplaynameHeader::
++
+HTTP header to retrieve the user's display name from. Only used if `auth.type`
+is set to `HTTP`.
++
+If set, Gerrit trusts and enforces the user's full name using the HTTP header
+and disables the ability to manually modify the user's full name
+from the contact information page.
+
+[[auth.httpEmailHeader]]auth.httpEmailHeader::
++
+HTTP header to retrieve the user's e-mail from. Only used if `auth.type`
+is set to `HTTP`.
++
+If set, Gerrit trusts and enforces the user's e-mail using the HTTP header
+and disables the ability to manually modify or register other e-mails
+from the contact information page.
+
[[auth.loginUrl]]auth.loginUrl::
+
URL to redirect a browser to after the end-user has clicked on the
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
index 9a42866..2cea40d 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
@@ -137,7 +137,8 @@
fields.add(n);
}
}
- if (emailSender != null && emailSender.isEnabled()) {
+ if (emailSender != null && emailSender.isEnabled()
+ && realm.allowsEdit(Account.FieldName.REGISTER_NEW_EMAIL)) {
fields.add(Account.FieldName.REGISTER_NEW_EMAIL);
}
config.setEditableAccountFields(fields);
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
index adca95e..75a7e07 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
@@ -61,6 +61,8 @@
private final byte[] signInRaw;
private final byte[] signInGzip;
private final String loginHeader;
+ private final String displaynameHeader;
+ private final String emailHeader;
@Inject
HttpAuthFilter(final Provider<WebSession> webSession,
@@ -78,6 +80,8 @@
loginHeader = firstNonNull(
emptyToNull(authConfig.getLoginHttpHeader()),
AUTHORIZATION);
+ displaynameHeader = emptyToNull(authConfig.getHttpDisplaynameHeader());
+ emailHeader = emptyToNull(authConfig.getHttpEmailHeader());
}
@Override
@@ -174,6 +178,22 @@
}
}
+ String getRemoteDisplayname(HttpServletRequest req) {
+ if (displaynameHeader != null) {
+ return emptyToNull(req.getHeader(displaynameHeader));
+ } else {
+ return null;
+ }
+ }
+
+ String getRemoteEmail(HttpServletRequest req) {
+ if (emailHeader != null) {
+ return emptyToNull(req.getHeader(emailHeader));
+ } else {
+ return null;
+ }
+ }
+
String getLoginHeader() {
return loginHeader;
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java
index d2a25a8..0ba92eb 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java
@@ -110,6 +110,8 @@
}
final AuthRequest areq = AuthRequest.forUser(user);
+ areq.setDisplayName(authFilter.getRemoteDisplayname(req));
+ areq.setEmailAddress(authFilter.getRemoteEmail(req));
final AuthResult arsp;
try {
arsp = accountManager.authenticate(areq);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DefaultRealm.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DefaultRealm.java
index c90f3e9..d9fb303 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/DefaultRealm.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DefaultRealm.java
@@ -14,8 +14,11 @@
package com.google.gerrit.server.account;
+import com.google.common.base.Strings;
import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.Inject;
import java.util.Set;
@@ -23,17 +26,32 @@
public class DefaultRealm implements Realm {
private final EmailExpander emailExpander;
private final AccountByEmailCache byEmail;
+ private final AuthConfig authConfig;
@Inject
DefaultRealm(final EmailExpander emailExpander,
- final AccountByEmailCache byEmail) {
+ final AccountByEmailCache byEmail, final AuthConfig authConfig) {
this.emailExpander = emailExpander;
this.byEmail = byEmail;
+ this.authConfig = authConfig;
}
@Override
public boolean allowsEdit(final Account.FieldName field) {
- return true;
+ if (authConfig.getAuthType() == AuthType.HTTP) {
+ switch (field) {
+ case USER_NAME:
+ return false;
+ case FULL_NAME:
+ return Strings.emptyToNull(authConfig.getHttpDisplaynameHeader()) == null;
+ case REGISTER_NEW_EMAIL:
+ return Strings.emptyToNull(authConfig.getHttpEmailHeader()) == null;
+ default:
+ return true;
+ }
+ } else {
+ return true;
+ }
}
@Override
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
index f1c24cb..fc359c8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
@@ -36,6 +36,8 @@
public class AuthConfig {
private final AuthType authType;
private final String httpHeader;
+ private final String httpDisplaynameHeader;
+ private final String httpEmailHeader;
private final boolean trustContainerAuth;
private final boolean enableRunAs;
private final boolean userNameToLowerCase;
@@ -58,6 +60,8 @@
throws XsrfException {
authType = toType(cfg);
httpHeader = cfg.getString("auth", null, "httpheader");
+ httpDisplaynameHeader = cfg.getString("auth", null, "httpdisplaynameheader");
+ httpEmailHeader = cfg.getString("auth", null, "httpemailheader");
loginUrl = cfg.getString("auth", null, "loginurl");
logoutUrl = cfg.getString("auth", null, "logouturl");
openIdSsoUrl = cfg.getString("auth", null, "openidssourl");
@@ -126,6 +130,14 @@
return httpHeader;
}
+ public String getHttpDisplaynameHeader() {
+ return httpDisplaynameHeader;
+ }
+
+ public String getHttpEmailHeader() {
+ return httpEmailHeader;
+ }
+
public String getLoginUrl() {
return loginUrl;
}