feat: 自定义MFA认证逻辑 (#8891)

* feat: 自定义MFA认证

* feat: 修改翻译信息

Co-authored-by: halo <wuyihuangw@gmail.com>
Co-authored-by: Jiangjie.Bai <bugatti_it@163.com>
pull/9016/head
fit2bot 2022-11-04 14:29:15 +08:00 committed by GitHub
parent 2029e9f8df
commit 13ae50f5d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 181 additions and 93 deletions

View File

@ -2,7 +2,7 @@ from django.db.models import TextChoices
from authentication.confirm import CONFIRM_BACKENDS
from .confirm import ConfirmMFA, ConfirmPassword, ConfirmReLogin
from .mfa import MFAOtp, MFASms, MFARadius
from .mfa import MFAOtp, MFASms, MFARadius, MFACustom
RSA_PRIVATE_KEY = 'rsa_private_key'
RSA_PUBLIC_KEY = 'rsa_public_key'
@ -35,3 +35,4 @@ class MFAType(TextChoices):
OTP = MFAOtp.name, MFAOtp.display_name
SMS = MFASms.name, MFASms.display_name
Radius = MFARadius.name, MFARadius.display_name
Custom = MFACustom.name, MFACustom.display_name

View File

@ -1,5 +1,4 @@
from .otp import MFAOtp, otp_failed_msg
from .sms import MFASms
from .radius import MFARadius
MFA_BACKENDS = [MFAOtp, MFASms, MFARadius]
from .custom import MFACustom

View File

@ -0,0 +1,59 @@
from django.conf import settings
from django.utils.module_loading import import_string
from django.utils.translation import ugettext_lazy as _
from common.utils import get_logger
from .base import BaseMFA
logger = get_logger(__file__)
mfa_custom_method = None
if settings.MFA_CUSTOM:
""" 保证自定义认证方法在服务运行时不能被更改,只在第一次调用时加载一次 """
try:
mfa_custom_method_path = 'data.mfa.main.check_code'
mfa_custom_method = import_string(mfa_custom_method_path)
except Exception as e:
logger.warning('Import custom auth method failed: {}, Maybe not enabled'.format(e))
custom_failed_msg = _("MFA Custom code invalid")
class MFACustom(BaseMFA):
name = 'mfa_custom'
display_name = 'Custom'
placeholder = _("MFA custom verification code")
def check_code(self, code):
assert self.is_authenticated()
ok = False
try:
ok = mfa_custom_method(user=self.user, code=code)
except Exception as exc:
logger.error('Custom authenticate error: {}'.format(exc))
msg = '' if ok else custom_failed_msg
return ok, msg
def is_active(self):
return True
@staticmethod
def global_enabled():
return settings.MFA_CUSTOM and callable(mfa_custom_method)
def get_enable_url(self) -> str:
return ''
def can_disable(self):
return False
def disable(self):
return ''
@staticmethod
def help_text_of_disable():
return _("MFA custom global enabled, cannot disable")
def get_disable_url(self) -> str:
return ''

View File

@ -227,6 +227,10 @@ class Config(dict):
'AUTH_CUSTOM': False,
'AUTH_CUSTOM_FILE_MD5': '',
# Custom Config
'MFA_CUSTOM': False,
'MFA_CUSTOM_FILE_MD5': '',
# Auth LDAP settings
'AUTH_LDAP': False,
'AUTH_LDAP_SERVER_URI': 'ldap://localhost:389',

View File

@ -51,7 +51,6 @@ AUTH_LDAP_SYNC_CRONTAB = CONFIG.AUTH_LDAP_SYNC_CRONTAB
AUTH_LDAP_SYNC_ORG_ID = CONFIG.AUTH_LDAP_SYNC_ORG_ID
AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS = CONFIG.AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS
# ==============================================================================
# 认证 OpenID 配置参数
# 参考: https://django-oidc-rp.readthedocs.io/en/stable/settings.html
@ -180,7 +179,6 @@ if CONNECTION_TOKEN_EXPIRATION < 5 * 60:
# 最少5分钟
CONNECTION_TOKEN_EXPIRATION = 5 * 60
RBAC_BACKEND = 'rbac.backends.RBACBackend'
AUTH_BACKEND_MODEL = 'authentication.backends.base.JMSModelBackend'
AUTH_BACKEND_PUBKEY = 'authentication.backends.pubkey.PublicKeyAuthBackend'
@ -203,7 +201,7 @@ AUTHENTICATION_BACKENDS = [
# 只做权限校验
RBAC_BACKEND,
# 密码形式
AUTH_BACKEND_MODEL, AUTH_BACKEND_PUBKEY, AUTH_BACKEND_LDAP, AUTH_BACKEND_RADIUS,
AUTH_BACKEND_MODEL, AUTH_BACKEND_PUBKEY, AUTH_BACKEND_LDAP, AUTH_BACKEND_RADIUS,
# 跳转形式
AUTH_BACKEND_CAS, AUTH_BACKEND_OIDC_PASSWORD, AUTH_BACKEND_OIDC_CODE, AUTH_BACKEND_SAML2,
AUTH_BACKEND_OAUTH2,
@ -236,7 +234,22 @@ if AUTH_CUSTOM and AUTH_CUSTOM_FILE_MD5 == get_file_md5(AUTH_CUSTOM_FILE_PATH):
# 自定义认证模块
AUTHENTICATION_BACKENDS.append(AUTH_BACKEND_CUSTOM)
AUTHENTICATION_BACKENDS_THIRD_PARTY = [AUTH_BACKEND_OIDC_CODE, AUTH_BACKEND_CAS, AUTH_BACKEND_SAML2, AUTH_BACKEND_OAUTH2]
MFA_BACKEND_OTP = 'authentication.mfa.otp.MFAOtp'
MFA_BACKEND_RADIUS = 'authentication.mfa.radius.MFARadius'
MFA_BACKEND_SMS = 'authentication.mfa.sms.MFASms'
MFA_BACKEND_CUSTOM = 'authentication.mfa.custom.MFACustom'
MFA_BACKENDS = [MFA_BACKEND_OTP, MFA_BACKEND_RADIUS, MFA_BACKEND_SMS]
MFA_CUSTOM = CONFIG.MFA_CUSTOM
MFA_CUSTOM_FILE_MD5 = CONFIG.MFA_CUSTOM_FILE_MD5
MFA_CUSTOM_FILE_PATH = os.path.join(PROJECT_DIR, 'data', 'mfa', 'main.py')
if MFA_CUSTOM and MFA_CUSTOM_FILE_MD5 == get_file_md5(MFA_CUSTOM_FILE_PATH):
# 自定义多因子认证模块
MFA_BACKENDS.append(MFA_BACKEND_CUSTOM)
AUTHENTICATION_BACKENDS_THIRD_PARTY = [AUTH_BACKEND_OIDC_CODE, AUTH_BACKEND_CAS, AUTH_BACKEND_SAML2,
AUTH_BACKEND_OAUTH2]
ONLY_ALLOW_EXIST_USER_AUTH = CONFIG.ONLY_ALLOW_EXIST_USER_AUTH
ONLY_ALLOW_AUTH_FROM_SOURCE = CONFIG.ONLY_ALLOW_AUTH_FROM_SOURCE

View File

@ -1,3 +1,4 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7522cd9a7e7853d078c81006cea7f6dbe4fb9d51ae7c6dddd50e8471536d4c0d
size 133026
oid sha256:057dff28011cd49805396d87bd8dd17745f8f44d23bb5f26d7a29f581ffe206c
size 132904

View File

@ -30,9 +30,9 @@ msgstr "Acls"
#: orgs/models.py:70 perms/models/base.py:83 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/endpoint.py:14 terminal/models/endpoint.py:87
#: terminal/models/storage.py:27 terminal/models/task.py:16
#: terminal/models/terminal.py:101 users/forms/profile.py:33
#: users/models/group.py:15 users/models/user.py:669
#: terminal/models/storage.py:26 terminal/models/task.py:16
#: terminal/models/terminal.py:100 users/forms/profile.py:33
#: users/models/group.py:15 users/models/user.py:673
#: xpack/plugins/cloud/models.py:28
msgid "Name"
msgstr "名前"
@ -64,7 +64,6 @@ msgstr "アクティブ"
#: terminal/models/endpoint.py:22 terminal/models/endpoint.py:97
#: terminal/models/storage.py:30 terminal/models/terminal.py:115
#: tickets/models/comment.py:32 tickets/models/ticket/general.py:288
#: users/models/group.py:16 users/models/user.py:708
#: xpack/plugins/change_auth_plan/models/base.py:44
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116
#: xpack/plugins/gathered_user/models.py:26
@ -93,9 +92,6 @@ msgstr "ログイン確認"
#: orgs/models.py:220 perms/models/base.py:84 rbac/builtin.py:120
#: rbac/models/rolebinding.py:41 terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
#: terminal/models/sharing.py:33 terminal/notifications.py:94
#: terminal/notifications.py:142 tickets/models/comment.py:21 users/const.py:14
#: users/models/user.py:901 users/models/user.py:932
#: users/serializers/group.py:19
msgid "User"
msgstr "ユーザー"
@ -161,10 +157,6 @@ msgstr "コンマ区切り文字列の形式。* はすべて一致すること
#: authentication/models.py:260 authentication/serializers/password_mfa.py:25
#: authentication/templates/authentication/_msg_different_city.html:9
#: authentication/templates/authentication/_msg_oauth_bind.html:9
#: ops/models/adhoc.py:159 users/forms/profile.py:32 users/forms/profile.py:102
#: users/models/user.py:667 users/templates/users/_msg_user_created.html:12
#: users/templates/users/forgot_password.html:51
#: users/templates/users/forgot_password.html:98
#: xpack/plugins/change_auth_plan/models/asset.py:34
#: xpack/plugins/change_auth_plan/models/asset.py:195
#: xpack/plugins/cloud/serializers/account_attrs.py:26
@ -363,8 +355,6 @@ msgstr "タイプ表示"
#: authentication/models.py:22 common/db/models.py:116
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
#: orgs/models.py:72 orgs/models.py:223 perms/models/base.py:92
#: users/models/group.py:18 users/models/user.py:933
#: xpack/plugins/change_auth_plan/models/base.py:45
#: xpack/plugins/cloud/models.py:125
msgid "Date created"
msgstr "作成された日付"
@ -644,10 +634,6 @@ msgid "Labels"
msgstr "ラベル"
#: assets/models/asset.py:229 assets/models/base.py:183
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:56
#: assets/models/cmd_filter.py:103 assets/models/group.py:21
#: common/db/models.py:114 common/mixins/models.py:49 orgs/models.py:71
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:716
#: users/serializers/group.py:33
#: xpack/plugins/change_auth_plan/models/base.py:48
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
@ -872,7 +858,7 @@ msgid "Default"
msgstr "デフォルト"
#: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6
#: users/models/user.py:918
#: users/models/user.py:920
msgid "System"
msgstr "システム"
@ -881,7 +867,7 @@ msgid "Default Cluster"
msgstr "デフォルトクラスター"
#: assets/models/cmd_filter.py:34 perms/models/base.py:86
#: users/models/group.py:31 users/models/user.py:675
#: users/models/group.py:31 users/models/user.py:679
msgid "User group"
msgstr "ユーザーグループ"
@ -1180,7 +1166,7 @@ msgstr "定期的なパフォーマンス"
msgid "Currently only mail sending is supported"
msgstr "現在、メール送信のみがサポートされています"
#: assets/serializers/base.py:16 users/models/user.py:699
#: assets/serializers/base.py:16 users/models/user.py:701
msgid "Private key"
msgstr "ssh秘密鍵"
@ -1574,7 +1560,7 @@ msgstr "ユーザーエージェント"
#: audits/models.py:144
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: users/forms/profile.py:65 users/models/user.py:692
#: users/forms/profile.py:65 users/models/user.py:696
#: users/serializers/profile.py:126
msgid "MFA"
msgstr "MFA"
@ -1653,20 +1639,19 @@ msgstr "認証トークン"
#: audits/signal_handlers.py:61 authentication/notifications.py:73
#: authentication/views/login.py:73 authentication/views/wecom.py:178
#: notifications/backends/__init__.py:11 settings/serializers/auth/wecom.py:10
#: users/models/user.py:730
#: notifications/backends/__init__.py:11 users/models/user.py:732
msgid "WeCom"
msgstr "企業微信"
#: audits/signal_handlers.py:62 authentication/views/feishu.py:144
#: authentication/views/login.py:85 notifications/backends/__init__.py:14
#: settings/serializers/auth/feishu.py:10 users/models/user.py:732
#: users/models/user.py:734
msgid "FeiShu"
msgstr "本を飛ばす"
#: audits/signal_handlers.py:63 authentication/views/dingtalk.py:179
#: authentication/views/login.py:79 notifications/backends/__init__.py:12
#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:731
#: users/models/user.py:733
msgid "DingTalk"
msgstr "DingTalk"
@ -1969,6 +1954,18 @@ msgstr "動的コード"
msgid "Please input security code"
msgstr "セキュリティコードを入力してください"
#: authentication/mfa/custom.py:20
msgid "MFA Custom code invalid"
msgstr "カスタム MFA 検証コードの検証に失敗しました"
#: authentication/mfa/custom.py:26
msgid "MFA custom verification code"
msgstr "カスタム MFA 検証コード"
#: authentication/mfa/custom.py:56
msgid "MFA custom global enabled, cannot disable"
msgstr "カスタム MFA はグローバルに有効になっており、無効にすることはできません"
#: authentication/mfa/otp.py:7
msgid "OTP code invalid, or server time error"
msgstr "OTPコードが無効、またはサーバー時間エラー"
@ -2053,7 +2050,7 @@ msgstr "ひみつ"
#: authentication/models.py:74 authentication/models.py:264
#: perms/models/base.py:90 tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:713
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:715
msgid "Date expired"
msgstr "期限切れの日付"
@ -2183,14 +2180,14 @@ msgid "Show"
msgstr "表示"
#: authentication/templates/authentication/_access_key_modal.html:66
#: settings/serializers/security.py:39 users/models/user.py:556
#: settings/serializers/security.py:39 users/models/user.py:557
#: users/serializers/profile.py:116 users/templates/users/mfa_setting.html:61
#: users/templates/users/user_verify_mfa.html:36
msgid "Disable"
msgstr "無効化"
#: authentication/templates/authentication/_access_key_modal.html:67
#: users/models/user.py:557 users/serializers/profile.py:117
#: users/models/user.py:558 users/serializers/profile.py:117
#: users/templates/users/mfa_setting.html:26
#: users/templates/users/mfa_setting.html:68
msgid "Enable"
@ -2239,7 +2236,7 @@ msgstr "コードエラー"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
#: jumpserver/conf.py:402 ops/tasks.py:145 ops/tasks.py:148
#: jumpserver/conf.py:406 ops/tasks.py:145 ops/tasks.py:148
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@ -2723,11 +2720,11 @@ msgstr "特殊文字を含むべきではない"
msgid "The mobile phone number format is incorrect"
msgstr "携帯電話番号の形式が正しくありません"
#: jumpserver/conf.py:401
#: jumpserver/conf.py:405
msgid "Create account successfully"
msgstr "アカウントを正常に作成"
#: jumpserver/conf.py:403
#: jumpserver/conf.py:407
msgid "Your account has been created successfully"
msgstr "アカウントが正常に作成されました"
@ -2771,9 +2768,8 @@ msgstr ""
msgid "Notifications"
msgstr "通知"
#: notifications/backends/__init__.py:10 settings/serializers/email.py:19
#: settings/serializers/email.py:50 users/forms/profile.py:102
#: users/models/user.py:671
#: notifications/backends/__init__.py:10 users/forms/profile.py:102
#: users/models/user.py:675
msgid "Email"
msgstr "メール"
@ -3023,7 +3019,7 @@ msgid "Can view all joined org"
msgstr "参加しているすべての組織を表示できます"
#: orgs/models.py:222 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: users/models/user.py:679
#: users/models/user.py:683
msgid "Role"
msgstr "ロール"
@ -5781,27 +5777,27 @@ msgstr "公開鍵は古いものと同じであってはなりません。"
msgid "Not a valid ssh public key"
msgstr "有効なssh公開鍵ではありません"
#: users/forms/profile.py:161 users/models/user.py:702
#: users/forms/profile.py:161 users/models/user.py:704
msgid "Public key"
msgstr "公開キー"
#: users/models/user.py:558
#: users/models/user.py:559
msgid "Force enable"
msgstr "強制有効"
#: users/models/user.py:625
#: users/models/user.py:629
msgid "Local"
msgstr "ローカル"
#: users/models/user.py:681 users/serializers/user.py:149
#: users/models/user.py:685 users/serializers/user.py:149
msgid "Is service account"
msgstr "サービスアカウントです"
#: users/models/user.py:683
#: users/models/user.py:687
msgid "Avatar"
msgstr "アバター"
#: users/models/user.py:686
#: users/models/user.py:690
msgid "Wechat"
msgstr "微信"
@ -5831,6 +5827,8 @@ msgid "Need update password"
msgstr "更新パスワードが必要"
#: users/models/user.py:903
msgid "Can invite user"
msgstr "ユーザーを招待できます"

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a1e0b5e70491c6228017987091e46d14ccde03b6e56bfb330d1604240c6b3d09
size 109554
oid sha256:8bc04011b7295eb6f5a7557e581a430b29013756ec872c71b1812d40f64853e8
size 109464

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-02 10:13+0800\n"
"POT-Creation-Date: 2022-09-23 15:38+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -63,7 +63,7 @@ msgstr "激活中"
#: terminal/models/endpoint.py:22 terminal/models/endpoint.py:97
#: terminal/models/storage.py:30 terminal/models/terminal.py:115
#: tickets/models/comment.py:32 tickets/models/ticket/general.py:288
#: users/models/group.py:16 users/models/user.py:708
#: users/models/group.py:16 users/models/user.py:710
#: xpack/plugins/change_auth_plan/models/base.py:44
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116
#: xpack/plugins/gathered_user/models.py:26
@ -91,9 +91,9 @@ msgstr "登录复核"
#: perms/models/base.py:84 rbac/builtin.py:120 rbac/models/rolebinding.py:41
#: terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
#: terminal/models/sharing.py:33 terminal/notifications.py:94
#: terminal/notifications.py:142 tickets/models/comment.py:21 users/const.py:14
#: users/models/user.py:901 users/models/user.py:932
#: terminal/models/sharing.py:33 terminal/notifications.py:91
#: terminal/notifications.py:139 tickets/models/comment.py:21 users/const.py:14
#: users/models/user.py:903 users/models/user.py:934
#: users/serializers/group.py:19
msgid "User"
msgstr "用户"
@ -159,10 +159,8 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
#: authentication/models.py:260 authentication/serializers/password_mfa.py:25
#: authentication/templates/authentication/_msg_different_city.html:9
#: authentication/templates/authentication/_msg_oauth_bind.html:9
#: ops/models/adhoc.py:159 users/forms/profile.py:32 users/forms/profile.py:102
#: users/models/user.py:667 users/templates/users/_msg_user_created.html:12
#: users/templates/users/forgot_password.html:51
#: users/templates/users/forgot_password.html:98
#: ops/models/adhoc.py:159 users/forms/profile.py:32 users/models/user.py:671
#: users/templates/users/_msg_user_created.html:12
#: xpack/plugins/change_auth_plan/models/asset.py:34
#: xpack/plugins/change_auth_plan/models/asset.py:195
#: xpack/plugins/cloud/serializers/account_attrs.py:26
@ -350,14 +348,13 @@ msgstr "类型名称"
#: applications/serializers/application.py:105 assets/models/asset.py:230
#: assets/models/base.py:181 assets/models/cluster.py:26
#: assets/models/cmd_filter.py:53 assets/models/domain.py:26
#: assets/models/gathered_user.py:19 assets/models/group.py:22
#: assets/models/label.py:25 assets/serializers/account.py:18
#: assets/serializers/cmd_filter.py:28 assets/serializers/cmd_filter.py:48
#: common/db/models.py:116 common/mixins/models.py:50 ops/models/adhoc.py:39
#: ops/models/command.py:30 orgs/models.py:72 orgs/models.py:223
#: perms/models/base.py:92 users/models/group.py:18 users/models/user.py:933
#: xpack/plugins/change_auth_plan/models/base.py:45
#: assets/models/domain.py:26 assets/models/gathered_user.py:19
#: assets/models/group.py:22 assets/models/label.py:25
#: assets/serializers/account.py:18 assets/serializers/cmd_filter.py:28
#: assets/serializers/cmd_filter.py:48 common/db/models.py:114
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
#: orgs/models.py:72 orgs/models.py:223 perms/models/base.py:92
#: users/models/group.py:18 users/models/user.py:935
#: xpack/plugins/cloud/models.py:125
msgid "Date created"
msgstr "创建日期"
@ -637,10 +634,10 @@ msgid "Labels"
msgstr "标签管理"
#: assets/models/asset.py:229 assets/models/base.py:183
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:56
#: assets/models/cmd_filter.py:103 assets/models/group.py:21
#: common/db/models.py:114 common/mixins/models.py:49 orgs/models.py:71
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:716
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
#: assets/models/cmd_filter.py:99 assets/models/group.py:21
#: common/db/models.py:112 common/mixins/models.py:49 orgs/models.py:71
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:718
#: users/serializers/group.py:33
#: xpack/plugins/change_auth_plan/models/base.py:48
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
@ -865,7 +862,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6
#: users/models/user.py:918
#: users/models/user.py:920
msgid "System"
msgstr "系统"
@ -874,7 +871,7 @@ msgid "Default Cluster"
msgstr "默认Cluster"
#: assets/models/cmd_filter.py:34 perms/models/base.py:86
#: users/models/group.py:31 users/models/user.py:675
#: users/models/group.py:31 users/models/user.py:679
msgid "User group"
msgstr "用户组"
@ -1170,7 +1167,7 @@ msgstr "定时执行"
msgid "Currently only mail sending is supported"
msgstr "当前只支持邮件发送"
#: assets/serializers/base.py:16 users/models/user.py:699
#: assets/serializers/base.py:16 users/models/user.py:701
msgid "Private key"
msgstr "ssh私钥"
@ -1560,7 +1557,7 @@ msgstr "用户代理"
#: audits/models.py:144
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: users/forms/profile.py:65 users/models/user.py:692
#: users/forms/profile.py:65 users/models/user.py:696
#: users/serializers/profile.py:126
msgid "MFA"
msgstr "MFA"
@ -1652,7 +1649,7 @@ msgstr "飞书"
#: audits/signal_handlers.py:63 authentication/views/dingtalk.py:179
#: authentication/views/login.py:79 notifications/backends/__init__.py:12
#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:731
#: users/models/user.py:733
msgid "DingTalk"
msgstr "钉钉"
@ -1944,6 +1941,18 @@ msgstr "动态码"
msgid "Please input security code"
msgstr "请输入动态安全码"
#: authentication/mfa/custom.py:20
msgid "MFA Custom code invalid"
msgstr "自定义 MFA 验证码校验失败"
#: authentication/mfa/custom.py:26
msgid "MFA custom verification code"
msgstr "自定义 MFA 验证码"
#: authentication/mfa/custom.py:56
msgid "MFA custom global enabled, cannot disable"
msgstr "自定义 MFA 全局开启,无法被禁用"
#: authentication/mfa/otp.py:7
msgid "OTP code invalid, or server time error"
msgstr "虚拟 MFA 验证码错误,或者服务器端时间不对"
@ -2028,7 +2037,7 @@ msgstr "密钥"
#: authentication/models.py:74 authentication/models.py:264
#: perms/models/base.py:90 tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:713
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:715
msgid "Date expired"
msgstr "失效日期"
@ -2154,14 +2163,14 @@ msgid "Show"
msgstr "显示"
#: authentication/templates/authentication/_access_key_modal.html:66
#: settings/serializers/security.py:39 users/models/user.py:556
#: settings/serializers/security.py:39 users/models/user.py:557
#: users/serializers/profile.py:116 users/templates/users/mfa_setting.html:61
#: users/templates/users/user_verify_mfa.html:36
msgid "Disable"
msgstr "禁用"
#: authentication/templates/authentication/_access_key_modal.html:67
#: users/models/user.py:557 users/serializers/profile.py:117
#: users/models/user.py:558 users/serializers/profile.py:117
#: users/templates/users/mfa_setting.html:26
#: users/templates/users/mfa_setting.html:68
msgid "Enable"
@ -2210,7 +2219,7 @@ msgstr "代码错误"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
#: jumpserver/conf.py:402 ops/tasks.py:145 ops/tasks.py:148
#: jumpserver/conf.py:406 ops/tasks.py:145 ops/tasks.py:148
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@ -2685,11 +2694,11 @@ msgstr "不能包含特殊字符"
msgid "The mobile phone number format is incorrect"
msgstr "手机号格式不正确"
#: jumpserver/conf.py:401
#: jumpserver/conf.py:405
msgid "Create account successfully"
msgstr "创建账号成功"
#: jumpserver/conf.py:403
#: jumpserver/conf.py:407
msgid "Your account has been created successfully"
msgstr "你的账号已创建成功"
@ -2979,7 +2988,7 @@ msgid "Can view all joined org"
msgstr "可以查看所有加入的组织"
#: orgs/models.py:222 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: users/models/user.py:679
#: users/models/user.py:683
msgid "Role"
msgstr "角色"
@ -5691,27 +5700,27 @@ msgstr "不能和原来的密钥相同"
msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/profile.py:161 users/models/user.py:702
#: users/forms/profile.py:161 users/models/user.py:704
msgid "Public key"
msgstr "SSH公钥"
#: users/models/user.py:558
#: users/models/user.py:559
msgid "Force enable"
msgstr "强制启用"
#: users/models/user.py:625
#: users/models/user.py:629
msgid "Local"
msgstr "数据库"
#: users/models/user.py:681 users/serializers/user.py:149
#: users/models/user.py:685 users/serializers/user.py:149
msgid "Is service account"
msgstr "服务账号"
#: users/models/user.py:683
#: users/models/user.py:687
msgid "Avatar"
msgstr "头像"
#: users/models/user.py:686
#: users/models/user.py:690
msgid "Wechat"
msgstr "微信"

View File

@ -16,6 +16,7 @@ from django.contrib.auth.models import AbstractUser
from django.contrib.auth.hashers import check_password
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import reverse
from django.utils.module_loading import import_string
from orgs.utils import current_org
from orgs.models import Organization
@ -602,8 +603,11 @@ class MFAMixin:
@staticmethod
def get_user_mfa_backends(user):
from authentication.mfa import MFA_BACKENDS
backends = [cls(user) for cls in MFA_BACKENDS if cls.global_enabled()]
backends = []
for cls in settings.MFA_BACKENDS:
cls = import_string(cls)
if cls.global_enabled():
backends.append(cls(user))
return backends
def get_active_mfa_backend_by_type(self, mfa_type):