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
This commit is contained in:
@@ -255,6 +255,24 @@ The "Sign In" link will send users directly to this URL.
|
|||||||
HTTP header to trust the username from, or unset to select HTTP basic
|
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`.
|
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::
|
[[auth.loginUrl]]auth.loginUrl::
|
||||||
+
|
+
|
||||||
URL to redirect a browser to after the end-user has clicked on the
|
URL to redirect a browser to after the end-user has clicked on the
|
||||||
|
@@ -137,7 +137,8 @@ class GerritConfigProvider implements Provider<GerritConfig> {
|
|||||||
fields.add(n);
|
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);
|
fields.add(Account.FieldName.REGISTER_NEW_EMAIL);
|
||||||
}
|
}
|
||||||
config.setEditableAccountFields(fields);
|
config.setEditableAccountFields(fields);
|
||||||
|
@@ -61,6 +61,8 @@ class HttpAuthFilter implements Filter {
|
|||||||
private final byte[] signInRaw;
|
private final byte[] signInRaw;
|
||||||
private final byte[] signInGzip;
|
private final byte[] signInGzip;
|
||||||
private final String loginHeader;
|
private final String loginHeader;
|
||||||
|
private final String displaynameHeader;
|
||||||
|
private final String emailHeader;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
HttpAuthFilter(final Provider<WebSession> webSession,
|
HttpAuthFilter(final Provider<WebSession> webSession,
|
||||||
@@ -78,6 +80,8 @@ class HttpAuthFilter implements Filter {
|
|||||||
loginHeader = firstNonNull(
|
loginHeader = firstNonNull(
|
||||||
emptyToNull(authConfig.getLoginHttpHeader()),
|
emptyToNull(authConfig.getLoginHttpHeader()),
|
||||||
AUTHORIZATION);
|
AUTHORIZATION);
|
||||||
|
displaynameHeader = emptyToNull(authConfig.getHttpDisplaynameHeader());
|
||||||
|
emailHeader = emptyToNull(authConfig.getHttpEmailHeader());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -174,6 +178,22 @@ class HttpAuthFilter implements Filter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
String getLoginHeader() {
|
||||||
return loginHeader;
|
return loginHeader;
|
||||||
}
|
}
|
||||||
|
@@ -110,6 +110,8 @@ class HttpLoginServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final AuthRequest areq = AuthRequest.forUser(user);
|
final AuthRequest areq = AuthRequest.forUser(user);
|
||||||
|
areq.setDisplayName(authFilter.getRemoteDisplayname(req));
|
||||||
|
areq.setEmailAddress(authFilter.getRemoteEmail(req));
|
||||||
final AuthResult arsp;
|
final AuthResult arsp;
|
||||||
try {
|
try {
|
||||||
arsp = accountManager.authenticate(areq);
|
arsp = accountManager.authenticate(areq);
|
||||||
|
@@ -14,8 +14,11 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.account;
|
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.Account;
|
||||||
|
import com.google.gerrit.reviewdb.client.AuthType;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.config.AuthConfig;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -23,18 +26,33 @@ import java.util.Set;
|
|||||||
public class DefaultRealm implements Realm {
|
public class DefaultRealm implements Realm {
|
||||||
private final EmailExpander emailExpander;
|
private final EmailExpander emailExpander;
|
||||||
private final AccountByEmailCache byEmail;
|
private final AccountByEmailCache byEmail;
|
||||||
|
private final AuthConfig authConfig;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DefaultRealm(final EmailExpander emailExpander,
|
DefaultRealm(final EmailExpander emailExpander,
|
||||||
final AccountByEmailCache byEmail) {
|
final AccountByEmailCache byEmail, final AuthConfig authConfig) {
|
||||||
this.emailExpander = emailExpander;
|
this.emailExpander = emailExpander;
|
||||||
this.byEmail = byEmail;
|
this.byEmail = byEmail;
|
||||||
|
this.authConfig = authConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allowsEdit(final Account.FieldName field) {
|
public boolean allowsEdit(final Account.FieldName field) {
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthRequest authenticate(final AuthRequest who) {
|
public AuthRequest authenticate(final AuthRequest who) {
|
||||||
|
@@ -36,6 +36,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class AuthConfig {
|
public class AuthConfig {
|
||||||
private final AuthType authType;
|
private final AuthType authType;
|
||||||
private final String httpHeader;
|
private final String httpHeader;
|
||||||
|
private final String httpDisplaynameHeader;
|
||||||
|
private final String httpEmailHeader;
|
||||||
private final boolean trustContainerAuth;
|
private final boolean trustContainerAuth;
|
||||||
private final boolean enableRunAs;
|
private final boolean enableRunAs;
|
||||||
private final boolean userNameToLowerCase;
|
private final boolean userNameToLowerCase;
|
||||||
@@ -58,6 +60,8 @@ public class AuthConfig {
|
|||||||
throws XsrfException {
|
throws XsrfException {
|
||||||
authType = toType(cfg);
|
authType = toType(cfg);
|
||||||
httpHeader = cfg.getString("auth", null, "httpheader");
|
httpHeader = cfg.getString("auth", null, "httpheader");
|
||||||
|
httpDisplaynameHeader = cfg.getString("auth", null, "httpdisplaynameheader");
|
||||||
|
httpEmailHeader = cfg.getString("auth", null, "httpemailheader");
|
||||||
loginUrl = cfg.getString("auth", null, "loginurl");
|
loginUrl = cfg.getString("auth", null, "loginurl");
|
||||||
logoutUrl = cfg.getString("auth", null, "logouturl");
|
logoutUrl = cfg.getString("auth", null, "logouturl");
|
||||||
openIdSsoUrl = cfg.getString("auth", null, "openidssourl");
|
openIdSsoUrl = cfg.getString("auth", null, "openidssourl");
|
||||||
@@ -126,6 +130,14 @@ public class AuthConfig {
|
|||||||
return httpHeader;
|
return httpHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHttpDisplaynameHeader() {
|
||||||
|
return httpDisplaynameHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHttpEmailHeader() {
|
||||||
|
return httpEmailHeader;
|
||||||
|
}
|
||||||
|
|
||||||
public String getLoginUrl() {
|
public String getLoginUrl() {
|
||||||
return loginUrl;
|
return loginUrl;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user