LDAP: Fetch attributes in Bind DN context option
This is feature is workaround for #2628 (JumpCloud) and some other services that allow LDAP search only under BindDN user account, but not allow any LDAP search query in logged user DN context. Such approach is an alternative to minimal permissions security pattern for BindDN user.release/v1.15
parent
e2f95c2845
commit
834d92a47b
|
@ -921,6 +921,7 @@ auths.attribute_username_placeholder = Leave empty to use sign-in form field val
|
|||
auths.attribute_name = First name attribute
|
||||
auths.attribute_surname = Surname attribute
|
||||
auths.attribute_mail = Email attribute
|
||||
auths.attributes_in_bind = Fetch attributes in Bind DN context
|
||||
auths.filter = User Filter
|
||||
auths.admin_filter = Admin Filter
|
||||
auths.ms_ad_sa = Ms Ad SA
|
||||
|
|
|
@ -23,6 +23,7 @@ type AuthenticationForm struct {
|
|||
AttributeName string
|
||||
AttributeSurname string
|
||||
AttributeMail string
|
||||
AttributesInBind bool
|
||||
Filter string
|
||||
AdminFilter string
|
||||
IsActive bool
|
||||
|
|
|
@ -31,6 +31,7 @@ type Source struct {
|
|||
AttributeName string // First name attribute
|
||||
AttributeSurname string // Surname attribute
|
||||
AttributeMail string // E-mail attribute
|
||||
AttributesInBind bool // fetch attributes in bind context (not user)
|
||||
Filter string // Query filter to validate entry
|
||||
AdminFilter string // Query filter to check if user is admin
|
||||
Enabled bool // if this source is disabled
|
||||
|
@ -130,14 +131,14 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
|
|||
}
|
||||
}
|
||||
|
||||
log.Trace("Binding with userDN: %s", userDN)
|
||||
err = l.Bind(userDN, passwd)
|
||||
if err != nil {
|
||||
log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err)
|
||||
return "", "", "", "", false, false
|
||||
if directBind || !ls.AttributesInBind {
|
||||
// binds user (checking password) before looking-up attributes in user context
|
||||
err = bindUser(l, userDN, passwd)
|
||||
if err != nil {
|
||||
return "", "", "", "", false, false
|
||||
}
|
||||
}
|
||||
|
||||
log.Trace("Bound successfully with userDN: %s", userDN)
|
||||
userFilter, ok := ls.sanitizedUserQuery(name)
|
||||
if !ok {
|
||||
return "", "", "", "", false, false
|
||||
|
@ -184,9 +185,28 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
|
|||
}
|
||||
}
|
||||
|
||||
if !directBind && ls.AttributesInBind {
|
||||
// binds user (checking password) after looking-up attributes in BindDN context
|
||||
err = bindUser(l, userDN, passwd)
|
||||
if err != nil {
|
||||
return "", "", "", "", false, false
|
||||
}
|
||||
}
|
||||
|
||||
return username_attr, name_attr, sn_attr, mail_attr, admin_attr, true
|
||||
}
|
||||
|
||||
func bindUser(l *ldap.Conn, userDN, passwd string) error {
|
||||
log.Trace("Binding with userDN: %s", userDN)
|
||||
err := l.Bind(userDN, passwd)
|
||||
if err != nil {
|
||||
log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err)
|
||||
return err
|
||||
}
|
||||
log.Trace("Bound successfully with userDN: %s", userDN)
|
||||
return err
|
||||
}
|
||||
|
||||
func ldapDial(ls *Source) (*ldap.Conn, error) {
|
||||
if ls.UseSSL {
|
||||
log.Debug("Using TLS for LDAP without verifying: %v", ls.SkipVerify)
|
||||
|
|
|
@ -81,6 +81,7 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig {
|
|||
AttributeName: form.AttributeName,
|
||||
AttributeSurname: form.AttributeSurname,
|
||||
AttributeMail: form.AttributeMail,
|
||||
AttributesInBind: form.AttributesInBind,
|
||||
Filter: form.Filter,
|
||||
AdminFilter: form.AdminFilter,
|
||||
Enabled: true,
|
||||
|
|
|
@ -79,6 +79,14 @@
|
|||
<label for="attribute_mail">{{.i18n.Tr "admin.auths.attribute_mail"}}</label>
|
||||
<input id="attribute_mail" name="attribute_mail" value="{{$cfg.AttributeMail}}" placeholder="e.g. mail" required>
|
||||
</div>
|
||||
{{if .Source.IsLDAP}}
|
||||
<div class="inline field">
|
||||
<div class="ui checkbox">
|
||||
<label><strong>{{.i18n.Tr "admin.auths.attributes_in_bind"}}</strong></label>
|
||||
<input name="attributes_in_bind" type="checkbox" {{if $cfg.AttributesInBind}}checked{{end}}>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<!-- SMTP -->
|
||||
|
|
Loading…
Reference in New Issue