Skip to content

Commit

Permalink
新增钉钉认证登录 Feature/dingding login (#2171)
Browse files Browse the repository at this point in the history
* add mongo db type management support

* 更新功能清单支持MongoDB账号管理

* refomat code by black

* add unittest for MySQL&MongoDB management function

* add dingding login

* add comment for setting dingding auth

* add log info for authentication

* fixed

* fixed

---------

Co-authored-by: 小圈圈 <rtttte@qq.com>
  • Loading branch information
quanbisen and hhyo authored May 29, 2023
1 parent 73cd611 commit f8f1a8e
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 4 deletions.
49 changes: 48 additions & 1 deletion archery/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
from datetime import timedelta
import environ
import requests
import logging

logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Expand All @@ -17,8 +23,13 @@
SECRET_KEY=(str, "hfusaf2m4ot#7)fkw#di2bu6(cv0@opwmafx5n#6=3d%x^hpl6"),
DATABASE_URL=(str, "mysql://root:@127.0.0.1:3306/archery"),
CACHE_URL=(str, "redis://127.0.0.1:6379/0"),
# 系统外部认证目前支持LDAP、OIDC、DINGDING三种,认证方式只能启用其中一种,如果启用多个,实际生效的只有一个,优先级LDAP > DINGDING > OIDC
ENABLE_LDAP=(bool, False),
ENABLE_OIDC=(bool, False),
ENABLE_DINGDING=(
bool,
False,
), # 钉钉认证方式参考文档:https://open.dingtalk.com/document/orgapp/tutorial-obtaining-user-personal-information
AUTH_LDAP_ALWAYS_UPDATE_USER=(bool, True),
AUTH_LDAP_USER_ATTR_MAP=(
dict,
Expand Down Expand Up @@ -236,7 +247,7 @@
INSTALLED_APPS += ("mozilla_django_oidc",)
MIDDLEWARE += ("mozilla_django_oidc.middleware.SessionRefresh",)
AUTHENTICATION_BACKENDS = (
"oidc.auth.OIDCAuthenticationBackend",
"common.authenticate.oidc_auth.OIDCAuthenticationBackend",
"django.contrib.auth.backends.ModelBackend",
)

Expand All @@ -260,6 +271,20 @@

LOGIN_REDIRECT_URL = "/"

# Dingding
ENABLE_DINGDING = env("ENABLE_DINGDING", False)
if ENABLE_DINGDING:
INSTALLED_APPS += ("django_auth_dingding",)
AUTHENTICATION_BACKENDS = (
"common.authenticate.dingding_auth.DingdingAuthenticationBackend",
"django.contrib.auth.backends.ModelBackend",
)
AUTH_DINGDING_AUTHENTICATION_CALLBACK_URL = env(
"AUTH_DINGDING_AUTHENTICATION_CALLBACK_URL"
)
AUTH_DINGDING_APP_KEY = env("AUTH_DINGDING_APP_KEY")
AUTH_DINGDING_APP_SECRET = env("AUTH_DINGDING_APP_SECRET")

# LDAP
ENABLE_LDAP = env("ENABLE_LDAP", False)
if ENABLE_LDAP:
Expand Down Expand Up @@ -293,6 +318,28 @@
) # 每次登录从ldap同步用户信息
AUTH_LDAP_USER_ATTR_MAP = env("AUTH_LDAP_USER_ATTR_MAP")

SUPPORTED_AUTHENTICATION = [
("LDAP", ENABLE_LDAP),
("DINGDING", ENABLE_DINGDING),
("OIDC", ENABLE_OIDC),
]
# 计算当前启用的外部认证方式数量
ENABLE_AUTHENTICATION_COUNT = len(
[enabled for (name, enabled) in SUPPORTED_AUTHENTICATION if enabled]
)
if ENABLE_AUTHENTICATION_COUNT > 0:
if ENABLE_AUTHENTICATION_COUNT > 1:
logger.warning(
"系统外部认证目前支持LDAP、DINGDING、OIDC三种,认证方式只能启用其中一种,如果启用多个,实际生效的只有一个,优先级LDAP > DINGDING > OIDC"
)
authentication = "" # 默认为空
for name, enabled in SUPPORTED_AUTHENTICATION:
if enabled:
authentication = name
break
logger.info("当前生效的外部认证方式:" + authentication)
logger.info("认证后端:" + AUTHENTICATION_BACKENDS.__str__())

# LOG配置
LOGGING = {
"version": 1,
Expand Down
1 change: 1 addition & 0 deletions archery/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
path("admin/", admin.site.urls),
path("api/", include(("sql_api.urls", "sql_api"), namespace="sql_api")),
path("oidc/", include("mozilla_django_oidc.urls")),
path("dingding/", include("django_auth_dingding.urls")),
path("", include(("sql.urls", "sql"), namespace="sql")),
]

Expand Down
Empty file added common/authenticate/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions common/authenticate/dingding_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django_auth_dingding import auth
from common.auth import init_user


class DingdingAuthenticationBackend(auth.DingdingAuthenticationBackend):
def create_user(self, claims):
"""Return object for a newly created user account."""
user = super().create_user(claims)
init_user(user)
return user
File renamed without changes.
2 changes: 2 additions & 0 deletions common/middleware/check_login_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"/oidc/callback/",
"/oidc/authenticate/",
"/oidc/logout/",
"/dingding/callback/",
"/dingding/authenticate/",
]

IGNORE_URL_RE = r"/api/(v1|auth)/\w+"
Expand Down
5 changes: 5 additions & 0 deletions common/templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<a href="/oidc/authenticate/">以OIDC登录</a>
</div>
{% endif %}
{% if dingding_enabled %}
<div class="form-group">
<a href="/dingding/authenticate/">以钉钉登录</a>
</div>
{% endif %}
</form>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ django-environ==0.8.1
alibabacloud_dysmsapi20170525==2.0.9
tencentcloud-sdk-python==3.0.656
mozilla-django-oidc==3.0.0
django-auth-dingding==0.0.2
5 changes: 2 additions & 3 deletions sql/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# -*- coding: UTF-8 -*-
import os
import traceback

import simplejson as json
from django.conf import settings

from django.contrib.auth.decorators import permission_required
Expand Down Expand Up @@ -65,7 +63,8 @@ def login(request):
"login.html",
context={
"sign_up_enabled": SysConfig().get("sign_up_enabled"),
"oidc_enabled": os.getenv("ENABLE_OIDC"),
"oidc_enabled": settings.ENABLE_OIDC,
"dingding_enabled": settings.ENABLE_DINGDING,
},
)

Expand Down

0 comments on commit f8f1a8e

Please sign in to comment.