自动认证
功能介绍#
在显示ArkID登录页面(密码、手机等)之前,系统会遍历自动登录插件(比如keberos)提供的 authenticate 方法,如果其中某个插件认证成功,那么就可以立即登录ArkID
实现思路#
- 进入ArkID系统之前会调用 /api/v1/login/ 接口,在这个接口的处理函数中,用URL Query Params和 /api/v1/login_process/ 作为参数渲染 templates/login_enter.html 模板返回给浏览器,浏览器执行模板中的javascript代码, 判断URL Query Parmas 中是否有token, 如果有,保存到localStorage中,如果没有,取localStorage中的token,最后,重定向浏览器到 /api/v1/login_process 并带上token和URL Query Parmas作为查询参数
- 进入 /api/v1/login_process/接口的处理函数后,会判断查询参数中是否有token,如果有token,验证token有效后,如果查询参数中有next, 直接重定向到next指向的URL,如果没有则重定向到前端登录页;如果没有token或者token失效, 那么分发AUTO_LOGIN事件,并遍历事件分发返回结果,如果其中某个自动认证插件认证成功并返回user,那么刷新该用户token,带上token重定向到 /api/v1/login/ ,如果所有的自动认证插件都认证失败,重定向到前端登录页
抽象方法#
提示
authenticate 认证成功应该返回user, 如果失败返回None,如果类似kerberos认证需要两次进入authenticate,第一次应该进入应该返回HttpResponse 状态码为401
基类定义#
arkid.core.extension.auto_auth.AutoAuthExtension (Extension)
#
Source code in arkid/core/extension/auto_auth.py
class AutoAuthExtension(Extension):
TYPE = "auto_auth"
composite_schema_map = {}
created_composite_schema_list = []
composite_key = 'type'
composite_model = TenantExtensionConfig
@property
def type(self):
return AutoAuthExtension.TYPE
def load(self):
self.listen_event(core_event.AUTO_LOGIN, self.authenticate)
super().load()
@abstractmethod
def authenticate(self, event, **kwargs):
"""
抽象方法
Args:
event (arkid.core.event.Event): 自动认证事件
Returns:
Union[arkid.core.models.User, django.http.HttpResponse, None]: 自动认证返回结果
"""
pass
def register_auto_auth_schema(self, schema, auto_auth_type):
self.register_config_schema(schema, self.package + '_' + auto_auth_type)
self.register_composite_config_schema(
schema, auto_auth_type, exclude=['extension']
)
composite_model (BaseModel)
django-model
#
TenantExtensionConfig(id, is_del, is_active, updated, created, tenant, extension, config, name, type)
Source code in arkid/core/extension/auto_auth.py
class TenantExtensionConfig(BaseModel):
class Meta(object):
verbose_name = _("插件运行时配置")
verbose_name_plural = _("插件运行时配置")
tenant = models.ForeignKey('core.Tenant', blank=False, on_delete=models.PROTECT, verbose_name=_('租户'))
extension = models.ForeignKey('Extension', blank=False, on_delete=models.PROTECT, verbose_name=_('插件'))
config = models.JSONField(blank=True, default=dict, verbose_name=_('Runtime Config','运行时配置'))
name = models.CharField(max_length=128, default='', verbose_name=_('名称'))
type = models.CharField(max_length=128, default='', verbose_name=_('类型'))
config: JSONField
blank
django-field
#
Runtime Config
created: DateTimeField
blank
django-field
nullable
#
创建时间
extension: ForeignKey
django-field
#
插件
id: UUIDField
django-field
#
ID
is_active: BooleanField
django-field
#
是否可用
is_del: BooleanField
django-field
#
是否删除
name: CharField
django-field
#
名称
tenant: ForeignKey
django-field
#
租户
type: CharField
django-field
#
类型
updated: DateTimeField
blank
django-field
nullable
#
更新时间
authenticate(self, event, **kwargs)
#
抽象方法
Parameters:
Name | Type | Description | Default |
---|---|---|---|
event |
arkid.core.event.Event |
自动认证事件 |
required |
Returns:
Type | Description |
---|---|
Union[arkid.core.models.User, django.http.HttpResponse, None] |
自动认证返回结果 |