Skip to content

自动认证

功能介绍#

在显示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]

自动认证返回结果

Source code in arkid/core/extension/auto_auth.py
@abstractmethod
def authenticate(self, event, **kwargs):
    """
    抽象方法
    Args:
        event (arkid.core.event.Event): 自动认证事件
    Returns:
        Union[arkid.core.models.User, django.http.HttpResponse, None]: 自动认证返回结果
    """
    pass

load(self) #

抽象方法,插件加载的入口方法

Source code in arkid/core/extension/auto_auth.py
def load(self):
    self.listen_event(core_event.AUTO_LOGIN, self.authenticate)

    super().load()

评论