Authing 文档文档
快速开始
概念
使用指南
开发集成 arrow
  • V2 文档
  • V3 文档
元数据
应用集成
身份自动化
加入 APN
开发集成
多租户(内测版)
控制台文档
多租户控制台
租户控制台
Saas 应用 Demo
快速开始
概念
使用指南
开发集成 arrow
  • V2 文档
  • V3 文档
元数据
应用集成
身份自动化
加入 APN
开发集成
多租户(内测版)
控制台文档
多租户控制台
租户控制台
Saas 应用 Demo
旧版
使用指南
  • 快速开始

  • 对用户进行认证

  • 对用户进行权限管理

  • 用户自助服务

  • 授权

  • 自适应 MFA

    • Authing CAMFA 概述
    • 基于 Authing Guard 接入 Authing 持续自适应 MFA
    • 改造已有的 IAM/IDaaS/认证系统接入 Authing 自适应 MFA 能力
    • 进阶 MFA:Continuous Adaptive Multi-Factor Authentication (CAMFA) 指南
    • 自适应 MFA 编排/策略配置说明
  • 管理用户账号

  • 管理用户目录

  • 同步中心

  • 应用

  • 成为联邦认证身份源

  • 连接外部身份源(IdP)

  • 微信生态全场景能力

  • 迁移用户到 Authing

  • 管理组织机构

  • 安全设置

  • 品牌化

  • 自动化

  • 审计日志

  • 设置

  • Authing 令牌
  • 私有化部署方案

  • 常见问题 FAQ

  1. 使用指南
  2. /
  3. 自适应 MFA

  4. /
  5. 改造已有的 IAM/IDaaS/认证系统接入 Authing 自适应 MFA 能力

¶ 改造已有的 IAM/IDaaS/认证系统接入 Authing 自适应 MFA 能力

我们将默认以下情况是您当前的目标和现状,我们将为您提供最佳的解决方案

目标:增强现有系统的登录认证安全性、保护企业的敏感数据和应用程序、同时提高用户体验 现状:已有的 IAM/IDaaS/ 认证系统主要是自研或第三方开发,安全能力较弱或 MFA 不具备动态自适应感知能力(例如办公设备切换、办公网络变更能自动唤起 MFA)。它们通常支持多种身份验证方式,例如用户名 / 密码、社交账号登录、手机验证码等。然而,这些系统仍然存在一些问题,例如密码泄露、社交账号被盗等。 解决方案:接入 Authing 安全策略引擎及 MFA 组件,快速提升安全感知能力

¶ 改造已有的 IAM/IDaaS/认证系统接入 Authing 自适应 MFA 能力的整体流程

改造已有的 IAM/IDaaS/认证系统接入 Authing 自适应 MFA 能力的整体流程

¶ Step 1. 创建 Authing MFA 应用

你需要先在 Authing 创建一个 MFA 应用。进入控制台 (opens new window)> 应用,点击右上角的「添加应用」。

创建 Authing MFA 应用

¶ Step 2. 基于 Authing 应用配置自适应 MFA

进入控制台 (opens new window) > 应用 >点击应用详情 >点击安全管理,找到多因素认证因子配置界面如下(点击对应开关即可启用认证因子): 创建应用

自适应 MFA 认证策略底层基于 Authing UEBA,可以针对用户行为和用户画像进行深度梳理分析,从而自动选择与当前行为相匹配的 MFA 策略。 在自适应 MFA 认证策略中,Authing UEBA 引擎会根据用户的行为和画像进行分析和判断,例如用户的登录历史、设备信息、IP 地址、地理位置、活动模式等等,从而确定当前用户的身份和风险级别,并选择与之相匹配的 MFA 策略。

¶ Step 3. 改造已有的 IAM/IDaaS/认证系统接入 Authing 自适应 MFA 能力

假定您的系统具有一个相对简单的登录认证流程,我们会据此为您展示如何一步一步为简单的登录认证流程添加 Authing 自适应 MFA 安全策略认证能力

¶ 我们为您推荐的改造已有系统接入 Authing 自适应 MFA 方案

以下是交互时序图 交互时序图

Live Demo For MFA (opens new window)

¶ 客户端改造方案
  • 在代码中安装 Authing MFA SDK, Authing SDK 并引入 AuthinMFA, MetadataClient
  • 使用 MetadataClient 获取当前系统中的用户行为数据,如 IP、浏览器等信息
  • 改造原有登录认证接口,传输用户行为数据到系统后台
  • 判断当前是否需要 MFA 认证
  • 如果需要进行 MFA,使用后端接口返回的 MFA trigger data 和 AuthinMFA 拉起 MFA 认证流程,进行 MFA 认证
  • 根据 MFA 认证结果,决定是否认证通过。如果认证通过,记录用户登录状态,跳转到业务系统;如果认证不通过,显示错误提示,返回登录页面 服务端改造方案
  • 在代码中安装 Authing SDK,引入 AuthenticationClient、MetadataManagementClient,并进行初始化
  • 改造登录接口接收并携带认证状态上报用户行为数据到 Authing 系统
  • 用户行为数据上报后,如果用户一次认证通过后,调用 Authing 安全策略引擎计算本次认证是否触发 MFA
  • 如果触发 MFA,将本次进行 MFA 的 trigger data 返回给客户端;如果不进行 MFA,则验证通过
¶ 服务端改造方案
  • 在代码中安装 Authing SDK,引入 AuthenticationClient、MetadataManagementClient,并进行初始化
  • 改造登录接口接收并携带认证状态上报用户行为数据到 Authing 系统
  • 用户行为数据上报后,如果用户一次认证通过后,调用 Authing 安全策略引擎计算本次认证是否触发 MFA
  • 如果触发 MFA,将本次进行 MFA 的 trigger data 返回给客户端;如果不进行 MFA,则验证通过
¶ 以一个简单的应用系统登录代码示例,帮助您来理解如何进行对系统的逐步改造

我们假定您登录系统的客户端、服务端代码如下所示,它足够简单易于理解

¶ 客户端代码:
// 客户端代码示例

// 获取当前用户的用户名及密码
const username = form.username
const password = form.password

// 携带用户名及密码向服务端发起认证请求
const loginResult = clientLogin(username, password)

// 根据登录结果判断是否进行后续操作
if(loginResult.status) {
    // 1. 记录登录状态
    // 2. 跳转到业务系统
} else {
    // 1. 界面提示认证失败
    // 2. 返回登录界面
}
¶ 服务端代码:
// 服务端代码示例

// 服务端登录认证方法
function login(username, password) {
    
    // 查询当前认证用户
    const user = db.findByUsername(username)
    
    // 判断用户密码是否正确
    if(user.password === md5(password)) {
        return {
            status: true,
            token: jwt(user)
        }
    } else {
        return {
            status: false,
            message: '账号或密码错误'
        }
    }
}

¶ Step 3.1 客户端代码改造示例

¶ Step 3.1.1 安装并在代码中引入 Authing MFA SDK(用于拉起 MFA 前端界面), Authing SDK(用于上报用户行为数据)

$ npm install authing-js-sdk
$ npm install @authing/mfa
import { MetadataClient } from 'authing-js-sdk'
import { AuthingMFA } from '@authing/mfa'

const appId = 'AUHTING_APP_ID'
const appSecret = 'AUHTING_APP_SECRET'

const authingMetadataClient = new MetadataClient()

¶ Step 3.1.2 使用 Metadata Client 获取当前系统中的用户行为数据,如 IP、浏览器等信息

Metadata Client 是 Authing 为客户提供的开箱即用的元数据快速生成工具包,帮助客户快速接入 Authing 元数据平台,它内置了 Authing 平台几十种内置元数据类型,关于 Metadata Client 的使用方法可以参考:元数据 SDK 使用文档,在本示例中主要用于上报用户行为数据

// load 方法采集客户端所在环境信息,以 json 存储,比如 IP、DeviceType(当前请求设备类型)、SystemType(当前操作系统类型)、BrowserType(当前请求浏览器类型) 等
const metadata = authingMetadataClient.authingUEBA.load()

¶ Step 3.1.3 改造原有登录认证接口,传输用户行为数据到系统后台

// 通过 login 接口将用户行为数据传到服务端
const loginResult = clientLogin(username, password, metadata)

¶ Step 3.1.4 判断当前是否需要 MFA 认证,如果需要进行 MFA,使用后端接口返回的 MFA trigger data 和 Authing MFA SDK 拉起 MFA 认证流程,进行 MFA 认证

// 判断服务端返回的登录结果、
if(loginResult.status) {
      // 1. 登录成功记录登录状态
     // 2. 跳转到业务系统
} else if(loginResult.mfaTriggerData){
    // 使用 AuthingMFA SDK 拉起 MFA 认证流程
    AuthingMFA(loginResult.mfaTriggerData).start().then(mfaToken => {
        // mfaToken 为用户 MFA 后生成的 jwt token
        // 可以使用 mfaToken 作为用户登录成功凭据,也可以基于当前 token 进行二次签发
    })
} else {
    // 5. 界面提示认证失败
}

¶ Step 3.1.5 根据 MFA 认证结果,决定是否认证通过。如果认证通过,记录用户登录状态,跳转到业务系统;如果认证不通过,显示错误提示,返回登录页面

// 使用 AuthingMFA SDK 拉起 MFA 认证流程
AuthingMFA(loginResult.mfaTriggerData).start().then(mfaToken => {
    // 可以使用 mfaToken 作为用户登录成功凭据,也可以基于当前 token 进行二次签发
    // 下面示例就是使用 mfaToken 进行二次签发的流程
    const myToken = clientReIssueToken(mfaToken)
    if(myToken) {
         // 1. 记录登录状态
         // 2. 跳转到业务系统
    } else {
        // 界面提示认证失败
    }
})

如果您选择使用 Authing mfaToken 作为用户认证 token,可参加如下代码

// 使用 AuthingMFA SDK 拉起 MFA 认证流程
AuthingMFA(loginResult.mfaTriggerData).start().then(mfaToken => {
    // TODO 验证 token 合法性
    
    // 可以使用 mfaToken 作为用户登录成功凭据,也可以基于当前 token 进行二次签发
    if(myToken) {
         // 1. 使用 mfaToken 记录登录状态
         // 2. 跳转到业务系统
    } else {
        // 界面提示认证失败
    }
}

¶ 客户端改造后代码整体如下所示

import { MetadataClient } from 'authing-js-sdk'
import { AuthingMFA } from '@authing/mfa'

const appId = 'AUHTING_APP_ID'
const appSecret = 'AUHTING_APP_SECRET'

const authingMetadataClient =  new MetadataClient()

// load 方法采集客户端所在环境信息,以 json 存储,比如 IP、DeviceType(当前请求设备类型)、SystemType(当前操作系统类型)、BrowserType(当前请求浏览器类型) 等
const metadata = authingMetadataClient.authingUEBA.load()

// 通过 login 接口将用户行为数据传到服务端
const loginResult = clientLogin(username, password, metadata)

// 判断服务端返回的登录结果、
if(loginResult.status) {
      // 1. 登录成功记录登录状态
     // 2. 跳转到业务系统
} else if(loginResult.mfaTriggerData){
    // 使用 AuthingMFA SDK 拉起 MFA 认证流程
    AuthingMFA(loginResult.mfaTriggerData).start().then(mfaToken => {
        // 可以使用 mfaToken 作为用户登录成功凭据,也可以基于当前 token 进行二次签发
        // 下面示例就是使用 mfaToken 进行二次签发的流程
        
        // TODO SDK verify
        const myToken = clientReIssueToken(mfaToken)
        if(myToken) {
             // 1. 记录登录状态
             // 2. 跳转到业务系统
        } else {
            // 界面提示认证失败
        }
    })
} else {
    // 5. 界面提示认证失败
}

¶ Step 3.2 服务端代码改造示例

¶ Step 3.2.1 在代码中安装 Authing SDK,引入 AuthenticationClient、MetadataManagementClient,并进行初始化

$ npm install authing-js-sdk
import { MetadataManagementClient, AuthenticationClient } from 'authing-js-sdk'
    
const appId = 'AUHTING_APP_ID'
const appSecret = 'AUHTING_APP_SECRET'

const authingMetadataManagementClient = new MetadataManagementClient({appId, appSecret})
const authingAuthenticationClient = new AuthenticationClient({appId})

¶ Step 3.2.2 改造登录接口,接收并携带认证状态,上报用户行为数据到 Authing 系统

const authingUEBA = authingMetadataManagementClient.authingUEBA

// 用户登录接口
function login(username, password, metadata) {
    // 查询当前认证用户
    const user = db.findByUsername(username)
    const loginStatus = user.password === md5(password)
    
    // 携带认证状态上报用户行为数据到 Authing 系统
    const clientUEBAMetadata = metadata
    const UEBAMetadata = await authingUEBA.capture({
        ...clientUEBAMetadata,
        loginStatus
    })
    
    // 如果认证失败,直接返回错误即可
    if(!loginStatus) {
        return {
            status: false,
            message: '账号或密码错误'
        }
    }
}
¶ 为什么要通过业务系统服务端转发用户行为数据

为什么要通过业务系统服务端转发用户行为数据

数据传到服务器是为了让数据更加安全、避免数据泄露、滥用和随意修改,同时也方便对数据持久化、确保数据不会丢失,同时也方便对数据进行处理、更好的挖掘数据的价值,以及支持数据共享、给其他应用程序或者设备使用。

¶ Step 3.2.3 调用 Authing 安全策略引擎计算本次认证是否触发 MFA

// 元数据上传成功后,调用认证侧 MFA 工作流(规定每个应用特定的 MFA 工作策略 Id 和 采集的元数据信息,得到元数据分析结果
const mfaTriggerData = authingAuthenticationClient.triggerWorkflow({
    'workflowId': 'xxx',
    'metadata': clientUEBAMetadata,// 用户所绑定 UEBA 元数据格式的数据
})

¶ Step 3.2.4 如果触发 MFA,将本次进行 MFA 的 trigger data 返回给客户端;如果不进行 MFA,则验证通过

const mfaTriggerData = authingAuthenticationClient.MFA.triggerWorkflow({
        'workflowId': 'xxx',
        'metadata': clientUEBAMetadata,// 用户所绑定 UEBA 元数据格式的数据
    })
    
if(mfaTriggerData) {
    return {
        status: false,
        mfaTriggerData: mfaTriggerData
    }
} else {
    return {
        status: true,
        token: jwt(user)
    }
}

¶ Step 3.2.5 添加全新接口,校验 MFA token 有效性,根据校验结果重新签发用户 Token

// MFA verify 接口
function clientReissueToken(mfaToken) {
    const mfaRes = authingAuthenticationClient.verify(mfaToken)
    // 如果 mfaToken 校验成功
    if(mfaRes.status) {
        // 取出 mfaToken 包含的 Id 信息
        const { originalIdentity } = mfaRes.data
        // 根据 Id 查询所包含的用户,如果用户存在则返回 Token 封装
        const user = db.findByUsername(originalIdentity)
        return {
            status: true,
            token: jwt(user)
        }
    } else {
    // 如果 mfaToken 校验失败,则返回失败信息
        return {
            status: false,
            message: mfaRes.message
        }
    }
}

¶ 服务端改造后代码整体如下所示

import { MetadataManagementClient, AuthenticationClient } from 'authing-js-sdk'

const appId = 'AUHTING_APP_ID'
const appSecret = 'AUHTING_APP_SECRET'

const authingMetadataManagementClient =  new MetadataManagementClient({appId, appSecret})
const authingAuthenticationClient =  new AuthenticationClient({appId})

const authingUEBA =  authingMetadataManagementClient.authingUEBA

// 用户登录接口
function login(username, password, metadata) {
    // 查询当前认证用户
    const user = db.findByUsername(username)
    const loginStatus = user.password === md5(password)
    
    // 携带认证状态上报用户行为数据到 Authing 系统
    const clientUEBAMetadata = metadata
    const UEBAMetadata = await authingUEBA.capture({
        ...clientUEBAMetadata,
        loginStatus
    })
    
    // 如果认证失败,直接返回错误即可
    if(!loginStatus) {
        return {
            status: false,
            message: '账号或密码错误'
        }
    }
    
    // 元数据上传成功后,调用认证侧 MFA 工作流(规定每个应用特定的 MFA 工作策略 Id 和 采集的元数据信息,得到元数据分析结果
    const mfaTriggerData = authingAuthenticationClient.triggerWorkflow({
        'workflowId': 'xxx',
        'metadata': clientUEBAMetadata,// 用户所绑定 UEBA 元数据格式的数据
    })
    
    if(mfaTriggerData) {
        return {
            status: false,
            mfaTriggerData: mfaTriggerData
        }
    } else {
        return {
            status: true,
            token: jwt(user)
        }
    }
}



// MFA verify 接口
function verifyMFA(mfaToken) {
    const mfaRes = authingAuthenticationClient.verify(mfaToken)
    // 如果 mfaToken 校验成功
    if(mfaRes.status) {
        // 取出 mfaToken 包含的 Id 信息
        const { originalIdentity } = mfaRes.data
        // 根据 Id 查询所包含的用户,如果用户存在则返回 Token 封装
        const user = db.findByUsername(originalIdentity)
        return {
            status: true,
            token: jwt(user)
        }
    } else {
    // 如果 mfaToken 校验失败,则返回失败信息
        return {
            status: false,
            message: mfaRes.message
        }
    }
}

¶ 更多功能了解请参考

  • Authing Adaptive MFA 概述
  • 基于 Authing Guard 登录组件接入 MFA
  • 进阶 MFA:Continuous Adaptive Multi-Factor Authentication (CAMFA) 指南
上一篇: 基于 Authing Guard 接入 Authing 持续自适应 MFA 下一篇: 进阶 MFA:Continuous Adaptive Multi-Factor Authentication (CAMFA) 指南
  • 改造已有的 IAM/IDaaS/认证系统接入 Authing 自适应 MFA 能力的整体流程
  • 更多功能了解请参考

用户身份管理

集成第三方登录
手机号闪验 (opens new window)
通用登录表单组件
自定义认证流程

企业内部管理

单点登录
多因素认证
权限管理

开发者

开发文档
框架集成
博客 (opens new window)
GitHub (opens new window)
社区用户中心 (opens new window)

公司

400 888 2106
sales@authing.cn
北京市朝阳区北辰世纪中心 B 座 16 层(总)
成都市高新区天府五街 200 号 1 号楼 B 区 4 楼 406 室(分)

京ICP备19051205号

beian京公网安备 11010802035968号

© 北京蒸汽记忆科技有限公司