Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新增钉钉认证登录 Feature/dingding login #2171

Merged
merged 13 commits into from
May 29, 2023
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
LeoQuote marked this conversation as resolved.
Show resolved Hide resolved
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