Bind to LDAP using only the end-user identity
When auth.type = LDAP_BIND the actual username and password supplied by the end user is used to connect to the LDAP server to query for account information. This permits Gerrit to be connected to secured directory servers, without requiring a generic user account for Gerrit itself. To avoid breaking existing installations that rely upon the account query to determine the DN for the authentication bind this new mode uses the new LDAP_BIND auth type setting. Bug: issue 423 Change-id: I8ec3adc36ae3f2363d344521d02755a2b385db0b Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -63,6 +63,23 @@ it then verifies by performing a simple bind against the configured
|
||||
<<ldap.server,ldap.server>>. In this configuration the web server
|
||||
is not involved in the user authentication process.
|
||||
+
|
||||
The actual username used in the LDAP simple bind request is the
|
||||
account's full DN, which is discovered by first querying the
|
||||
directory using either an anonymous request, or the configured
|
||||
<<ldap.username>> identity.
|
||||
|
||||
* `LDAP_BIND`
|
||||
+
|
||||
Gerrit prompts the user to enter a username and a password, which
|
||||
it then verifies by performing a simple bind against the configured
|
||||
<<ldap.server,ldap.server>>. In this configuration the web server
|
||||
is not involved in the user authentication process.
|
||||
+
|
||||
Unlike LDAP above, the username used to perform the LDAP simple bind
|
||||
request is the exact string supplied by in the dialog by the user.
|
||||
The configured <<ldap.username>> identity is not used to obtain
|
||||
account information.
|
||||
+
|
||||
* `DEVELOPMENT_BECOME_ANY_ACCOUNT`
|
||||
+
|
||||
*DO NOT USE*. Only for use in a development environment.
|
||||
|
@@ -304,6 +304,7 @@ public class Dispatcher {
|
||||
new OpenIdSignInDialog(mode, to, msg).center();
|
||||
break;
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
new UserPassSignInDialog(to, msg).center();
|
||||
break;
|
||||
default:
|
||||
|
@@ -189,6 +189,7 @@ public class Gerrit implements EntryPoint {
|
||||
break;
|
||||
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
new UserPassSignInDialog(token, null).center();
|
||||
break;
|
||||
}
|
||||
@@ -442,6 +443,7 @@ public class Gerrit implements EntryPoint {
|
||||
break;
|
||||
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
if (cfg.getRegisterUrl() != null) {
|
||||
menuRight.add(anchor(C.menuRegister(), cfg.getRegisterUrl()));
|
||||
}
|
||||
|
@@ -222,6 +222,7 @@ public class AccountGroupScreen extends AccountScreen {
|
||||
switch (Gerrit.getConfig().getAuthType()) {
|
||||
case HTTP_LDAP:
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
@@ -76,6 +76,7 @@ class GerritConfigProvider implements Provider<GerritConfig> {
|
||||
final GerritConfig config = new GerritConfig();
|
||||
switch (authConfig.getAuthType()) {
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
config.setRegisterUrl(cfg.getString("auth", null, "registerurl"));
|
||||
break;
|
||||
}
|
||||
|
@@ -101,6 +101,7 @@ public class WebModule extends FactoryModule {
|
||||
break;
|
||||
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
install(new LdapAuthModule());
|
||||
break;
|
||||
|
||||
|
@@ -57,6 +57,7 @@ class InitAuth implements InitStep {
|
||||
|
||||
switch (auth_type) {
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
case HTTP_LDAP: {
|
||||
String server =
|
||||
ldap.string("LDAP server", "server", "ldap://localhost");
|
||||
|
@@ -20,8 +20,8 @@ import com.google.gwtorm.client.StringKey;
|
||||
/** Association of an external account identifier to a local {@link Account}. */
|
||||
public final class AccountExternalId {
|
||||
/**
|
||||
* Scheme used for {@link AuthType#LDAP}, {@link AuthType#HTTP}, and
|
||||
* {@link AuthType#HTTP_LDAP} usernames.
|
||||
* Scheme used for {@link AuthType#LDAP}, {@link AuthType#HTTP},
|
||||
* {@link AuthType#HTTP_LDAP}, and {@link AuthType#LDAP_BIND} usernames.
|
||||
* <p>
|
||||
* The name {@code gerrit:} was a very poor choice.
|
||||
*/
|
||||
|
@@ -47,6 +47,17 @@ public enum AuthType {
|
||||
*/
|
||||
LDAP,
|
||||
|
||||
/**
|
||||
* Login collects username and password through a web form, and binds to LDAP.
|
||||
* <p>
|
||||
* Unlike {@link #HTTP_LDAP}, Gerrit presents a sign-in dialog to the user and
|
||||
* makes the connection to the LDAP server on their behalf.
|
||||
* <p>
|
||||
* Unlike the more generic {@link #LDAP} mode, Gerrit can only query the
|
||||
* directory via an actual authenticated user account.
|
||||
*/
|
||||
LDAP_BIND,
|
||||
|
||||
/** Development mode to enable becoming anyone you want. */
|
||||
DEVELOPMENT_BECOME_ANY_ACCOUNT;
|
||||
}
|
||||
|
@@ -307,7 +307,12 @@ class LdapRealm implements Realm {
|
||||
throws AccountException {
|
||||
final String username = who.getLocalUser();
|
||||
try {
|
||||
final DirContext ctx = open();
|
||||
final DirContext ctx;
|
||||
if (authConfig.getAuthType() == AuthType.LDAP_BIND) {
|
||||
ctx = authenticate(username, who.getPassword());
|
||||
} else {
|
||||
ctx = open();
|
||||
}
|
||||
try {
|
||||
final LdapQuery.Result m = findAccount(ctx, username);
|
||||
|
||||
@@ -541,13 +546,14 @@ class LdapRealm implements Realm {
|
||||
return new InitialDirContext(env);
|
||||
}
|
||||
|
||||
private void authenticate(String dn, String password) throws AccountException {
|
||||
private DirContext authenticate(String dn, String password)
|
||||
throws AccountException {
|
||||
final Properties env = createContextProperties();
|
||||
env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
env.put(Context.SECURITY_PRINCIPAL, dn);
|
||||
env.put(Context.SECURITY_CREDENTIALS, password != null ? password : "");
|
||||
try {
|
||||
new InitialDirContext(env).close();
|
||||
return new InitialDirContext(env);
|
||||
} catch (NamingException e) {
|
||||
throw new AccountException("Incorrect username or password", e);
|
||||
}
|
||||
|
@@ -123,6 +123,7 @@ public class AuthConfig {
|
||||
case HTTP:
|
||||
case HTTP_LDAP:
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
// Its safe to assume yes for an HTTP authentication type, as the
|
||||
// only way in is through some external system that the admin trusts
|
||||
//
|
||||
|
@@ -82,6 +82,7 @@ public class GerritGlobalModule extends FactoryModule {
|
||||
switch (loginType) {
|
||||
case HTTP_LDAP:
|
||||
case LDAP:
|
||||
case LDAP_BIND:
|
||||
install(new LdapModule());
|
||||
break;
|
||||
|
||||
|
Reference in New Issue
Block a user