mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 00:57:44 +01:00
update ldap configuration
This commit is contained in:
parent
0fc7363a4c
commit
ad78449266
@ -26,10 +26,25 @@ auth_mode = db_auth
|
||||
#The url for an ldap endpoint.
|
||||
ldap_url = ldaps://ldap.mydomain.com
|
||||
|
||||
#ldap_searchdn, set the user who has the permission to search the LDAP/AD server. If your ldap/AD server does not support anonymous search, you should configure it and ldap_search_pwd.
|
||||
#ldap_searchdn = cn=admin,ou=people,dc=mydomain,dc=com
|
||||
|
||||
#the password of the ldap_searchdn
|
||||
#ldap_search_pwd = admin
|
||||
|
||||
#The basedn template to look up a user in LDAP and verify the user's password.
|
||||
#For AD server, uses this template:
|
||||
#ldap_basedn = CN=%s,OU=Dept1,DC=mydomain,DC=com
|
||||
ldap_basedn = uid=%s,ou=people,dc=mydomain,dc=com
|
||||
ldap_basedn = ou=people,dc=mydomain,dc=com
|
||||
|
||||
#ldap filter, set the attribute to filter a user, you can add as many as you need, be sure the grammar is right. If needed, configure it.
|
||||
#ldap_filter = objectClass=person
|
||||
|
||||
#the exclusive attribute to distinguish a user, it can be uid or cn or mail or email or sAMAccountName, for example: ldap_uid = uid
|
||||
ldap_uid = uid
|
||||
|
||||
#ldap_scope, set the scope to search, 1-LDAP_SCOPE_BASE, 2-LDAP_SCOPE_ONELEVEL, 3-LDAP_SCOPE_SUBTREE, default is 3
|
||||
ldap_scope = 3
|
||||
|
||||
#The password for the root user of mysql db, change this before any production use.
|
||||
db_password = root123
|
||||
|
@ -47,7 +47,21 @@ email_ssl = rcp.get("configuration", "email_ssl")
|
||||
harbor_admin_password = rcp.get("configuration", "harbor_admin_password")
|
||||
auth_mode = rcp.get("configuration", "auth_mode")
|
||||
ldap_url = rcp.get("configuration", "ldap_url")
|
||||
# this two options are either both set or unset
|
||||
if rcp.has_option("configuration", "ldap_searchdn"):
|
||||
ldap_searchdn = rcp.get("configuration", "ldap_searchdn")
|
||||
ldap_search_pwd = rcp.get("configuration", "ldap_search_pwd")
|
||||
else:
|
||||
ldap_searchdn = ""
|
||||
ldap_search_pwd = ""
|
||||
ldap_basedn = rcp.get("configuration", "ldap_basedn")
|
||||
# ldap_filter is null by default
|
||||
if rcp.has_option("configuration", "ldap_filter"):
|
||||
ldap_filter = rcp.get("configuration", "ldap_filter")
|
||||
else:
|
||||
ldap_filter = ""
|
||||
ldap_uid = rcp.get("configuration", "ldap_uid")
|
||||
ldap_scope = rcp.get("configuration", "ldap_scope")
|
||||
db_password = rcp.get("configuration", "db_password")
|
||||
self_registration = rcp.get("configuration", "self_registration")
|
||||
use_compressed_js = rcp.get("configuration", "use_compressed_js")
|
||||
@ -118,7 +132,12 @@ render(os.path.join(templates_dir, "ui", "env"),
|
||||
auth_mode=auth_mode,
|
||||
harbor_admin_password=harbor_admin_password,
|
||||
ldap_url=ldap_url,
|
||||
ldap_searchdn =ldap_searchdn,
|
||||
ldap_search_pwd =ldap_search_pwd,
|
||||
ldap_basedn=ldap_basedn,
|
||||
ldap_filter=ldap_filter,
|
||||
ldap_uid=ldap_uid,
|
||||
ldap_scope=ldap_scope,
|
||||
self_registration=self_registration,
|
||||
use_compressed_js=use_compressed_js,
|
||||
ui_secret=ui_secret,
|
||||
|
@ -10,7 +10,12 @@ HARBOR_ADMIN_PASSWORD=$harbor_admin_password
|
||||
HARBOR_URL=$ui_url
|
||||
AUTH_MODE=$auth_mode
|
||||
LDAP_URL=$ldap_url
|
||||
LDAP_SEARCH_DN=$ldap_searchdn
|
||||
LDAP_SEARCH_PWD=$ldap_search_pwd
|
||||
LDAP_BASE_DN=$ldap_basedn
|
||||
LDAP_FILTER=$ldap_filter
|
||||
LDAP_UID=$ldap_uid
|
||||
LDAP_SCOPE=$ldap_scope
|
||||
UI_SECRET=$ui_secret
|
||||
SELF_REGISTRATION=$self_registration
|
||||
USE_COMPRESSED_JS=$use_compressed_js
|
||||
|
@ -40,62 +40,96 @@ const metaChars = "&|!=~*<>()"
|
||||
// be associated to other entities in the system.
|
||||
func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
||||
|
||||
ldapURL := os.Getenv("LDAP_URL")
|
||||
if ldapURL == "" {
|
||||
return nil, errors.New("Can not get any available LDAP_URL.")
|
||||
}
|
||||
log.Debug("ldapURL:", ldapURL)
|
||||
|
||||
p := m.Principal
|
||||
for _, c := range metaChars {
|
||||
if strings.ContainsRune(p, c) {
|
||||
return nil, fmt.Errorf("the principal contains meta char: %q", c)
|
||||
}
|
||||
}
|
||||
|
||||
ldapURL := os.Getenv("LDAP_URL")
|
||||
if ldapURL == "" {
|
||||
return nil, errors.New("Can not get any available LDAP_URL.")
|
||||
}
|
||||
log.Debug("ldapURL:", ldapURL)
|
||||
ldap, err := openldap.Initialize(ldapURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3)
|
||||
|
||||
ldapBaseDn := os.Getenv("LDAP_BASE_DN")
|
||||
if ldapBaseDn == "" {
|
||||
return nil, errors.New("Can not get any available LDAP_BASE_DN.")
|
||||
}
|
||||
log.Debug("baseDn:", ldapBaseDn)
|
||||
|
||||
baseDn := fmt.Sprintf(ldapBaseDn, m.Principal)
|
||||
log.Debug("baseDn:", baseDn)
|
||||
ldapSearchDn := os.Getenv("LDAP_SEARCH_DN")
|
||||
if ldapSearchDn != "" {
|
||||
log.Debug("Search DN: ", ldapSearchDn)
|
||||
ldapSearchPwd := os.Getenv("LDAP_SEARCH_PWD")
|
||||
err = ldap.Bind(ldapSearchDn, ldapSearchPwd)
|
||||
if err != nil {
|
||||
log.Debug("Bind search dn error", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = ldap.Bind(baseDn, m.Password)
|
||||
attrName := os.Getenv("LDAP_UID")
|
||||
filter := os.Getenv("LDAP_FILTER")
|
||||
if filter != "" {
|
||||
filter = "(&(" + filter + ")(" + attrName + "=" + m.Principal + "))"
|
||||
} else {
|
||||
filter = "(" + attrName + "=" + m.Principal + ")"
|
||||
}
|
||||
log.Debug("one or more filter", filter)
|
||||
|
||||
ldapScope := os.Getenv("LDAP_SCOPE")
|
||||
var scope int
|
||||
if ldapScope == "1" {
|
||||
scope = openldap.LDAP_SCOPE_BASE
|
||||
} else if ldapScope == "2" {
|
||||
scope = openldap.LDAP_SCOPE_ONELEVEL
|
||||
} else {
|
||||
scope = openldap.LDAP_SCOPE_SUBTREE
|
||||
}
|
||||
attributes := []string{"uid", "cn", "mail", "email"}
|
||||
result, err := ldap.SearchAll(ldapBaseDn, scope, filter, attributes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(result.Entries()) == 0 {
|
||||
log.Warningf("Not found an entry.")
|
||||
return nil, nil
|
||||
} else if len(result.Entries()) != 1 {
|
||||
log.Warningf("Found more than one entry.")
|
||||
return nil, nil
|
||||
}
|
||||
en := result.Entries()[0]
|
||||
bindDN := en.Dn()
|
||||
log.Debug("found entry:", en)
|
||||
err = ldap.Bind(bindDN, m.Password)
|
||||
if err != nil {
|
||||
log.Debug("Bind user error", err)
|
||||
return nil, err
|
||||
}
|
||||
defer ldap.Close()
|
||||
|
||||
scope := openldap.LDAP_SCOPE_SUBTREE // LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
|
||||
filter := "objectClass=*"
|
||||
attributes := []string{"mail"}
|
||||
|
||||
result, err := ldap.SearchAll(baseDn, scope, filter, attributes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := models.User{}
|
||||
if len(result.Entries()) == 1 {
|
||||
en := result.Entries()[0]
|
||||
for _, attr := range en.Attributes() {
|
||||
val := attr.Values()[0]
|
||||
if attr.Name() == "mail" {
|
||||
u.Email = val
|
||||
}
|
||||
for _, attr := range en.Attributes() {
|
||||
val := attr.Values()[0]
|
||||
switch attr.Name() {
|
||||
case "uid":
|
||||
u.Realname = val
|
||||
case "cn":
|
||||
u.Realname = val
|
||||
case "mail":
|
||||
u.Email = val
|
||||
case "email":
|
||||
u.Email = val
|
||||
}
|
||||
}
|
||||
|
||||
u.Username = m.Principal
|
||||
log.Debug("username:", u.Username, ",email:", u.Email)
|
||||
|
||||
exist, err := dao.UserExists(u, "username")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -48,7 +48,12 @@ The parameters are described below - note that at the very least, you will need
|
||||
* **harbor_admin_password**: The adminstrator's password. _Note that the default username/password are **admin/Harbor12345** ._
|
||||
* **auth_mode**: The type of authentication that is used. By default it is **db_auth**, i.e. the credentials are stored in a database. For LDAP authentication, set this to **ldap_auth**.
|
||||
* **ldap_url**: The LDAP endpoint URL (e.g. `ldaps://ldap.mydomain.com`). _Only used when **auth_mode** is set to *ldap_auth* ._
|
||||
* **ldap_searchdn**: The dn of the user who has the permission to search a ldap/AD server (e.g. `cn=admin,ou=people,dc=mydomain,dc=com`).
|
||||
* **ldap_search_pwd**: The password of the user who was set as the ldap_searchdn.
|
||||
* **ldap_basedn**: The basedn template for verifying the user's credential against an LDAP (e.g. `uid=%s,ou=people,dc=mydomain,dc=com` ) or an AD (e.g. `CN=%s,OU=Dept1,DC=mydomain,DC=com`) server. _Only used when **auth_mode** is set to *ldap_auth* ._
|
||||
* **ldap_filter**:The attribute to filter a user, you can add as many as you need, be sure the grammar is right. If not needed, comment it (e.g. `ldap_filter = objectClass=person`).
|
||||
* **ldap_uid**:The exclusive attribute to distinguish a user, it can be uid or cn or mail or email(e.g. `ldap_uid = uid`).
|
||||
* **ldap_scope**:The scope to search, 1-LDAP_SCOPE_BASE, 2-LDAP_SCOPE_ONELEVEL, 3-LDAP_SCOPE_SUBTREE, default is 3(e.g. `ldap_scope = 3`).
|
||||
* **db_password**: The root password for the mySQL database used for **db_auth**. _Change this password for any production use!_
|
||||
* **self_registration**: (**on** or **off**. Default is **on**) Enable / Disable the ability for a user to register themselves. When disabled, new users can only be created by the Admin user, only an admin user can create new users in Harbor. _NOTE: When **auth_mode** is set to **ldap_auth**, self-registration feature is **always** disabled, and this flag is ignored._
|
||||
* **use_compressed_js**: (**on** or **off**. Default is **on**) For production use, turn this flag to **on**. In development mode, set it to **off** so that js files can be modified separately.
|
||||
|
Loading…
Reference in New Issue
Block a user