通过LDAP的Geonode身份验证¶
此软件包提供使用LDAP作为geonode的身份验证和授权后端的实用程序。
这个 django_auth_ldap 包是添加LDAP与Django项目集成的一种非常有效的方式。它在将LDAP用户映射到geonode用户方面提供了很大的灵活性,并且能够管理用户身份验证。
但是,为了完全支持将LDAP组映射到geonode,并强制实施对资源的组权限,需要自定义geonode身份验证后端。这个contrib包提供了这样一个后端,它基于 django_auth_ldap 。
安装¶
安装此contrib软件包需要执行以下操作:
安装地理节点
安装系统LDAP库(需要开发包)
本地克隆此存储库
更改为 ldap 目录并安装此contrib软件包
# 1. install geonode (not shown here for brevity)
# 2. install systemwide LDAP libraries
sudo apt install \
libldap2-dev \
libsasl2-dev
# 3. get geonode/contribs code
git clone https://github.com/GeoNode/geonode-contribs.git
# 4. install geonode ldap contrib package
cd geonode-contribs/ldap
pip install .
配置¶
添加
geonode_ldap.backend.GeonodeLdapBackend
作为额外的身份验证后端。# e.g. by updating your settings.py or local_settings.py AUTHENTICATION_BACKENDS += ( "geonode_ldap.backend.GeonodeLdapBackend", )
您可以使用其他身份验证后端,Django身份验证框架会根据设置中列出的顺序尝试所有这些后端。这意味着可以这样设置geonode:允许内部组织用户使用其LDAP凭据登录,同时允许临时用户使用他们的Facebook登录(只要您启用了Facebook社交身份验证提供程序)。
注解
姜戈一家
django.contrib.auth.backends.ModelBackend
还必须使用才能提供与LDAP的完全地理节点集成。但是,这在GeoNode上默认包含settings
# The GeoNode default settings are the following AUTHENTICATION_BACKENDS = ( 'oauth2_provider.backends.OAuth2Backend', 'django.contrib.auth.backends.ModelBackend', 'guardian.backends.ObjectPermissionBackend', 'allauth.account.auth_backends.AuthenticationBackend', )
设置一些附加配置值。其中一些变量以前缀
AUTH_LDAP
(它们由以下人员直接使用 django_auth_ldap ),而其他则以前缀GEONODE_LDAP
(它们由以下人员使用geonode_ldap
)。geonode自定义变量包括:GEONODE_LDAP_GROUP_PROFILE_FILTERSTR
+这是一个带有过滤的ldap搜索片段,允许查询现有组。请参见下面的示例GEONODE_LDAP_GROUP_NAME_ATTRIBUTE
-这是将用于派生地理节点组名称的LDAP属性的名称。如果未指定,则默认为 cn ,这意味着LDAP对象的 common name 将用于生成地理结点组的名称GEONODE_LDAP_GROUP_PROFILE_MEMBER_ATTR
- This is the name of the LDAP attribute that will be used for deriving the geonode membership. If not specified it will default tomember
示例配置:
# add these import lines to the top of your geonode settings file
from django_auth_ldap import config as ldap_config
from geonode_ldap.config import GeonodeNestedGroupOfNamesType
import ldap
# enable logging
import logging
logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
# add both standard ModelBackend auth and geonode.contrib.ldap auth
AUTHENTICATION_BACKENDS += (
'geonode_ldap.backend.GeonodeLdapBackend',
)
# django_auth_ldap configuration
AUTH_LDAP_SERVER_URI = os.getenv("LDAP_SERVER_URL")
AUTH_LDAP_BIND_DN = os.getenv("LDAP_BIND_DN")
AUTH_LDAP_BIND_PASSWORD = os.getenv("LDAP_BIND_PASSWORD")
AUTH_LDAP_USER_SEARCH = ldap_config.LDAPSearch(
os.getenv("LDAP_USER_SEARCH_DN"),
ldap.SCOPE_SUBTREE,
os.getenv("LDAP_USER_SEARCH_FILTERSTR")
)
# should LDAP groups be used to spawn groups in GeoNode?
AUTH_LDAP_MIRROR_GROUPS = strtobool(os.getenv("LDAP_MIRROR_GROUPS", 'True'))
AUTH_LDAP_GROUP_SEARCH = ldap_config.LDAPSearch(
os.getenv("LDAP_GROUP_SEARCH_DN"),
ldap.SCOPE_SUBTREE,
os.getenv("LDAP_GROUP_SEARCH_FILTERSTR")
)
AUTH_LDAP_GROUP_TYPE = GeonodeNestedGroupOfNamesType()
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mailPrimaryAddress"
}
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_MIRROR_GROUPS_EXCEPT = [
"test_group"
]
# these are not needed by django_auth_ldap - we use them to find and match
# GroupProfiles and GroupCategories
GEONODE_LDAP_GROUP_NAME_ATTRIBUTE = os.getenv("LDAP_GROUP_NAME_ATTRIBUTE", default="cn")
GEONODE_LDAP_GROUP_PROFILE_FILTERSTR = os.getenv("LDAP_GROUP_SEARCH_FILTERSTR", default='(ou=research group)')
GEONODE_LDAP_GROUP_PROFILE_MEMBER_ATTR = os.getenv("LDAP_GROUP_PROFILE_MEMBER_ATTR", default='member')
示例环境变量:
LDAP_SERVER_URL=ldap://<the_ldap_server>
LDAP_BIND_DN=uid=ldapinfo,cn=users,dc=ad,dc=example,dc=org
LDAP_BIND_PASSWORD=<something_secret>
LDAP_USER_SEARCH_DN=dc=ad,dc=example,dc=org
LDAP_USER_SEARCH_FILTERSTR=(&(uid=%(user)s)(objectClass=person))
LDAP_MIRROR_GROUPS=True
LDAP_GROUP_SEARCH_DN=cn=groups,dc=ad,dc=example,dc=org
LDAP_GROUP_SEARCH_FILTERSTR=(|(cn=abt1)(cn=abt2)(cn=abt3)(cn=abt4)(cn=abt5)(cn=abt6))
LDAP_GROUP_PROFILE_MEMBER_ATTR=uniqueMember
上面示例中看到的配置将允许LDAP用户使用其LDAP凭据登录到geonode。
首次登录时,将根据LDAP用户及其LDAP属性创建一个geonode用户 cn
和 sn
用于填充geonode用户的 first_name
和 last_name
配置文件字段。
LDAP中用户所属的任何组(位于 cn=groups,dc=ad,dc=example,dc=org
搜索库,并且属于以下其中之一 (|(cn=abt1)(cn=abt2)(cn=abt3)(cn=abt4)(cn=abt5)(cn=abt6))
组)将被映射到相应的geonode组,甚至在geonode中创建这些组,以防它们尚不存在。geonode用户也成为这些geonode组的成员。
每次登录时,系统都会根据从LDAP提取的信息重新评估用户的地理节点组成员身份。这个 AUTH_LDAP_MIRROR_GROUPS_EXCEPT
设置可用于指定不会重新评估其成员身份的组。
如果不应镜像任何LDAP组 LDAP_MIRROR_GROUPS
和 LDAP_MIRROR_GROUPS_EXCEPT
必须设置为 False
。
注解
从LDAP映射的用户将标记为 ldap
标签。这将用于使它们保持同步。
警告
如果您删除 ldap
标记后,用户将作为纯内部GeoNode用户受到威胁。
您也可以在用户登录之前提前手动生成地理节点组。在这种情况下,当用户登录且映射的LDAP组已存在时,仅将该用户添加到地理节点组
一定要结账离开。 django_auth_ldap 有关各种配置选项的详细信息,请参阅。
使用户和组保持同步¶
为了不间断地保留远程LDAP用户和组 已同步 使用GeoNode,您将需要定期运行一些特定的管理命令。
*/10 * * * * /opt/geonode/my-geonode/manage.sh updateldapgroups >> /var/log/cron.log 2>&1
*/10 * * * * /opt/geonode/my-geonode/manage.sh updateldapusers >> /var/log/cron.log 2>&1
其中 manage.sh
是一个类似于以下内容的bash脚本:
manage.sh
export $(grep -v '^#' /opt/geonode/my-geonode/.env | xargs -d '\n'); /home/<my_user>/.virtualenvs/geonode/bin/python /opt/geonode/my-geonode/manage.py $@
以及 /opt/geonode/my-geonode/.env
类似于以下内容:
/opt/geonode/my-geonode/.env
DEBUG=False
DJANGO_ALLOWED_HOSTS=<geonode_public_host>,localhost,127.0.0.1
DJANGO_DATABASE_URL=postgis://my_geonode:**********@localhost:5432/my_geonode_db
DEFAULT_BACKEND_UPLOADER=geonode.importer
DEFAULT_FROM_EMAIL=geonode@example.org
DJANGO_EMAIL_HOST=smtp.example.org
DJANGO_EMAIL_HOST_PASSWORD=**********
DJANGO_EMAIL_HOST_USER=geonode
DJANGO_EMAIL_PORT=465
DJANGO_EMAIL_USE_SSL=True
DJANGO_SETTINGS_MODULE=my_geonode.settings
DJANGO_SECRET_KEY=**********
OAUTH2_API_KEY=**********
PROXY_URL=/proxy/?url=
EXIF_ENABLED=True
EMAIL_ENABLE=True
TIME_ENABLED=True
ACCOUNT_OPEN_SIGNUP=True
ACCOUNT_APPROVAL_REQUIRED=True
ACCOUNT_EMAIL_REQUIRED=True
ACCOUNT_EMAIL_VERIFICATION=optional
AVATAR_GRAVATAR_SSL=True
GEONODE_DB_URL=postgis://my_geonode:**********@localhost:5432/my_geonode_data
GEOSERVER_ADMIN_PASSWORD=**********
GEOSERVER_LOCATION=https://<geonode_public_host>/geoserver/
GEOSERVER_PUBLIC_HOST=<geonode_public_host>
GEOSERVER_PUBLIC_LOCATION=https://<geonode_public_host>/geoserver/
GEOSERVER_WEB_UI_LOCATION=https://<geonode_public_host>/geoserver/
LDAP_SERVER_URL=ldap://<the_ldap_server>
LDAP_BIND_DN=uid=ldapinfo,cn=users,dc=ad,dc=example,dc=org
LDAP_BIND_PASSWORD=<something_secret>
LDAP_USER_SEARCH_DN=dc=ad,dc=example,dc=org
LDAP_USER_SEARCH_FILTERSTR=(&(uid=%(user)s)(objectClass=person))
LDAP_MIRROR_GROUPS=True
LDAP_GROUP_SEARCH_DN=cn=groups,dc=ad,dc=example,dc=org
LDAP_GROUP_SEARCH_FILTERSTR=(|(cn=abt1)(cn=abt2)(cn=abt3)(cn=abt4)(cn=abt5)(cn=abt6))
LDAP_GROUP_PROFILE_MEMBER_ATTR=uniqueMember
OGC_REQUEST_MAX_RETRIES=3
OGC_REQUEST_POOL_CONNECTIONS=100
OGC_REQUEST_POOL_MAXSIZE=100
OGC_REQUEST_TIMEOUT=60
SITEURL=https://<geonode_public_host>/
SITE_HOST_NAME=<geonode_public_host>
FREETEXT_KEYWORDS_READONLY=False
# Advanced Workflow Settings
ADMIN_MODERATE_UPLOADS=False
GROUP_MANDATORY_RESOURCES=False
GROUP_PRIVATE_RESOURCES=False
RESOURCE_PUBLISHING=False
注解
您可能希望使用相同的 /opt/geonode/my-geonode/.env
为您的 UWSGI
配置也包括:
[uwsgi]
socket = 0.0.0.0:8000
uid = <my_user>
gid = www-data
plugins = python3
virtualenv = /home/<my_user>/.virtualenvs/geonode
# set environment variables from .env file
env LANG=en_US.utf8
env LC_ALL=en_US.UTF-8
env LC_LANG=en_US.UTF-8
for-readline = /opt/geonode/my-geonode/.env
env = %(_)
endfor =
chdir = /opt/geonode/my-geonode
module = my_geonode.wsgi:application
processes = 12
threads = 2
enable-threads = true
master = true
# logging
# path to where uwsgi logs will be saved
logto = /storage/my_geonode/logs/geonode.log
daemonize = /storage/my_geonode/logs/geonode.log
touch-reload = /opt/geonode/my-geonode/my_geonode/wsgi.py
buffer-size = 32768
max-requests = 500
harakiri = 300 # respawn processes taking more than 5 minutes (300 seconds)
# limit-as = 1024 # avoid Errno 12 cannot allocate memory
harakiri-verbose = true
vacuum = true
thunder-lock = true
用于集中监控/分析的Geonode Logstash¶
通过此contrib应用程序以及GeoNode内部监控应用程序,管理员可以配置将指标数据发送到 集中式服务器 它伴随着 Logstash 。
因此,可以在应用程序外部可视化有关一个或多个GeoNode实例的统计数据和图表。将服务器配置为 ELK stack 例如,可以在Kibana仪表板上可视化这些信息。
如果您管理多个GeoNode实例,则该服务器可以从多个GeoNode接收数据,从而使这两个实例都可用 single-instance dashboards (指个别实例)和 全局控制面板 (针对整个实例集计算的统计信息)。
警告
如果设置变量为 USER_ANALYTICS_ENABLED 和 monitoring-enabled 设置为 False 。
概述¶
默认情况下,GeoNode将每隔一段时间向集中式服务器发送数据 3600秒 (1小时)因此,如果启用,监控应用将收集1小时聚合的数据。此时间间隔可以配置,请参阅下面的段落以了解如何配置。
格式化和压缩的数据将在 TCP 连接(在 443 standard port by default) through a scheduled celery task which basically logs information via python-logstash-async 。
警告
此功能需要 python-logstash-async 。
数据和事件格式¶
每次调用集中监控服务时,4种类型的 JSON 格式化的事件将发送到服务器:
实例概述
{ "format_version": "1.0", "instance": { "name": geonode instance HOSTNAME, "ip": geonode instance IP }, "time": { "startTime": UTC now - 1 hour (default) "endTime": UTC now }, "hits": total number of requests, "unique_visits": total number of unique sessions, "unique_visitors": total number of unique users, "registered_users": total number of registered users at the end time, "layers": total number of layers at the end time, "documents": total number of documents at the end time, "maps": total number of maps at the end time, "errors": total number of errors }
资源详细信息
{ "format_version": "1.0", "instance": { "name": geonode instance HOSTNAME, "ip": geonode instance IP }, "time": { "startTime": UTC now - 1 hour (default) "endTime": UTC now }, "resources": [ … { "type": resource type, "name": resource name, "url": resource URL, "hits": total number of requests about this resource, "unique_visits": total number of unique sessions about this resource, "unique_visitors": total number of unique users about this resource, "downloads": total number of resource downloads, "ogcHits": total number of OGC service requests about this resource, "publications": total number of publication events }, … ] }
国家/地区详细信息
{ "format_version": "1.0", "instance": { "name": geonode instance HOSTNAME, "ip": geonode instance IP }, "time": { "startTime": UTC now - 1 hour (default) "endTime": UTC now }, "countries": [ … { "name": country name, "hits": total number of requests about the country }, … ] }
UA(用户代理)系列详细信息
{ "format_version": "1.0", "instance": { "name": geonode instance HOSTNAME, "ip": geonode instance IP }, "time": { "startTime": UTC now - 1 day "endTime": UTC now }, "ua_families": [ … { "name": UA family name "hits": total number of requests about the UA family }, … ] }
这些消息将是 gzip 压缩以提高传输性能,并且它们应该由 logstash filter 在服务器端(请参见 Logstash配置 )。
配置¶
默认情况下,集中监控服务处于禁用状态,因为它需要内部监控处于活动状态,并且需要特定于服务的配置。
地理节点配置¶
让我们添加一个:
这个 Host IP地址和 Port 号码是必填的,时间也是必填的 间隔 (缺省情况下为3600秒),它定义了服务调用轮询(因此应该聚合数据的时间范围)。
注解
配置服务后,用户可以通过单击 测试连接 。它将测试与集中式服务器的连接,而不保存配置。
其他设置附带默认值:
数据库路径 -->本地Spatialite数据库,用于缓存发送和传输到Logstash服务器之间的事件(即使在进程重启和崩溃时也会缓存日志事件);
套接字超时 -->TCP连接超时(秒);
队列检查间隔 -->检查内部队列中是否有需要缓存到数据库中的新消息的时间间隔(秒);
队列事件刷新间隔 -->将缓存的事件从数据库发送到Logstash的时间间隔(秒);
队列事件刷新计数 -->从数据库发送到Logstash的缓存事件计数;
队列事件批量大小 -->一批发送到Logstash的最大事件数;
Logstash数据库超时 -->‘连接’Spatialite数据库的超时时间(秒)。
要更好地理解这些变量的含义,建议阅读 python-logstash-async options for the asynchronous processing and formatting 。
其他三个只读字段将可见:
上次成功交付 -->上次交付成功的时间戳(如果存在);
下一次计划交付 -->下一次定时交货的时间戳;
上次传递失败 -->上次传递失败的时间戳(如果存在)。
Logstash配置¶
日志堆栈配置示例:
input {
tcp {
port => <logstash_port_number>
codec => "gzip_lines"
}
}
filter {
json {
source => "message"
}
if [format_version] == "1.0" {
if [countries] {
split {
field => "countries"
}
}
if [resources] {
split {
field => "resources"
}
}
if [ua_families] {
split {
field => "ua_families"
}
}
mutate {
remove_field => "message"
}
}
geoip {
source => "[instance][ip]"
}
}
output {
elasticsearch {
hosts => "elasticsearch:<elastic_port_number>"
index => "logstash-%{[instance][name]}-%{+YYYY.MM.dd}"
user => "elastic"
password => "changeme"
}
stdout { codec => rubydebug }
}
用法¶
保存服务配置时,如果启用了监控,则GeoNode将创建/更新芹菜 Periodic Task 它将根据 间隔 已配置。
您可以在 周期性任务 管理员UI的部分:
这个 dispatch-metrics-task 任务:
任务详细信息:
警告
当禁用监视是 良好实践 以同时禁用相应的定期任务。
管理命令¶
启用监控插件时 (USER_ANALYTICS_ENABLED 和 monitoring-enabled 设置为 True )和一个 用于集中监控/分析的Geonode Logstash 配置后,Geonode会将指标数据(默认情况下为每小时)发送到外部服务器(该服务器随Logstash一起提供),以进行统计可视化和分析。
该命令可以使用 manage.py
剧本。不需要任何选项。
$ DJANGO_SETTINGS_MODULE=<your_settings_module> python manage.py dispatch_metrics
执行过程中可能引发的异常将报告到GeoNode日志。