2019 年 7 月

第 34 卷,第 7 期

[ASP.NET Core 3.0]

在 ASP.NET Core 中使用 AI 驱动的授权策略限制站点访问

作者:Stefano Tempesta

ASP.NET Core 引入声明授权机制,该机制接受自定义策略来限制对应用程序或部分应用程序的访问,具体取决于经过身份验证的用户的特定授权属性。在上一篇文章中,即于 2019 年 6 月发行的 MSDN 杂志中的《ASP.NET Core 中支持 AI 的生物识别安全》(msdn.com/magazine/mt833460),我提出了一个基于策略的模型,用于将授权逻辑与基础用户角色分离,并展示了在检测到未经授权的入侵时,如何专门使用此类授权策略限制对建筑的物理访问。在第二篇文章中,我将重点讨论安全摄像头的连接性、将数据流式传输到 Azure IoT 中心、触发授权流,并使用内置在 Azure 机器学习中的异常检测服务评估潜在入侵的严重性。

有关 ASP.NET Core 授权框架以及我的 Web API 的源代码的详细信息,请分别参阅 bit.ly/2VN9Hmobit.ly/2IXPZCo

限制访问

在我的场景中,对建筑的访问由授权策略控制,必须满足这些策略才能打开门锁。ASP.NET Core 3 提供了一个管理授权策略的内置框架,我在这个解决方案中利用了此框架,并通过 Web API 公开了它。考虑到这一点,图 1 描述了这样一种场景:一个人通过轻扫访问通行证请求进入某栋建筑,摄像头检测到此人的动作并捕捉其人脸、肢体和声音。读卡器和摄像头注册为 IoT 设备,并将录制的数据流式传输到 Azure IoT 中心。

授权流
图 1:授权流

在我的前一篇文章中,我介绍了如何使用 ASP.NET Core Web API 中的自定义授权策略检查的用户拥有的特定声明。这些声明被断言为人脸、肢体和声音的生物识别信息,通过 Azure 视觉和语音处理认知服务可以迅速识别。

现在,我将描述在 Azure IoT 中心中将摄像头注册为 IoT 设备的过程,以及触发授权流的规则的定义。

注册 IoT 设备

通常情况下,IoT 应用程序可以描述为发送数据以生成见解的工具(设备)。这些见解反过来又会生成改进业务或流程的操作。在我的应用程序中,一个示例是(IoT 设备)发送图像和语音数据的摄像头。这些数据被用来评估此人是否是他们所说的那个人(见解)。该见解用于对此人进行身份验证并向其授予对站点的访问权限(操作)。此解决方案在图 2 中的参考体系结构设计类似于建议的 Azure IoT 体系结构 (bit.ly/2I20Us2),它描述了两种处理遥测数据的方法:暖路径或冷路径。不同之处与延迟和数据访问需求有关。热路径在数据到达时近乎实时分析数据,具有非常低的延迟性。这就是用 Azure 认知服务触发视觉和语音识别,然后授权用户访问的案例。冷路径捕获历史遥测数据进行进一步处理,通常用于数据分析,在本解决方案中用于机器学习 (ML)。

Azure IoT 参考体系结构
图 2 Azure IoT 参考体系结构

注册设备将向其流式传输数据的云网关是 Azure IoT 中心,它是托管在云中的托管服务,充当中心消息中心,在其管理的设备和授权应用程序后端之间进行双向通信。IoT 中心既支持从设备到云的通信,也支持从云到设备的通信。它还支持多种消息传递模式,比如设备到云遥测、设备上的文件上传、控制来自云的设备的请求-应答方法,以及直接方法,这些都是不需要设备响应的云到设备命令。

设备必须在 IoT 中心注册才能连接。设备注册的手动过程(有很多!)之一是使用 Azure Cloud Shell。首先通过运行以下命令创建设备标识:

az iot hub device-identity create --hub-name YourIoTHubName
    --device-id MyDotnetDevice

YourIoTHubName 是 Azure 订阅者 IoT 中心的名称(有关如何使用 Azure 门户创建 IoT 中心的详细描述,请参阅bit.ly/2JEMnph),MyDotnetDevice 是正在注册的设备的名称。注册后,将需要设备的连接字符串来流式传输数据。运行此命令获得刚刚注册的设备的连接字符串:

az iot hub device-identity show-connection-string --hub-name YourIoTHubName
  --device-id MyDotnetDevice --output table

请注意设备连接字符串,它应该类似于:

HostName={YourIoTHubName}.azure-devices.net; DeviceId=MyNodeDevice;
  SharedAccessKey={YourSharedAccessKey}

还需要与事件中心兼容的终结点、与事件中心兼容的路径和访问策略中的主键,以便后端应用程序能够连接到 IoT 中心并检索消息。虽然 IoT 中心有一个预定义的“iothubowner”访问策略,可以完全控制中心,但建议为设备连接创建一个权限较低的策略。以下命令检索 IoT 中心的这些值:

az iot hub show --query properties.eventHubEndpoints.events.endpoint
  --name YourIoTHubName
az iot hub show --query properties.eventHubEndpoints.events.path
  --name YourIoTHubName
az iot hub policy show --name YourAccessPolicy --query primaryKey
  --hub-name YourIoTHubName

还可以使用 .NET 中的 Azure IoT 中心预配服务客户端将设备注册到 IoT 中心。将需要 Microsoft.Azure.Devices.Provisioning.Service 包作为先决条件,可以从 NuGet 将其安装到 Visual Studio 解决方案中。

图 3 中的 DeviceRegistrationAsync 方法使用设备的认可密钥注册基于受信任的平台模块 (TPM) 的设备,该密钥通常在制造时永久嵌入到硬件中。它还需要用于唯一标识设备的注册 ID。这可能与设备 ID 相同,也可能不同。对于基于 TPM 的设备,注册 ID 可能来自 TPM 本身,例如 TPM 认可密钥的 SHA-256 哈希。

图 3 DeviceRegistrationAsync 方法

using Microsoft.Azure.Devices.Provisioning.Service;
static async Task DeviceRegistrationAsync()
{
  Attestation attestation = new TpmAttestation("<TpmEndorsementKey>");
  IndividualEnrollment enrollment = new IndividualEnrollment(
    "<RegistrationId>", attestation)
  {
    DeviceId = "DeviceId"
  };
  var serviceClient = ProvisioningServiceClient.CreateFromConnectionString(
    "<ConnectionString>");
  IndividualEnrollment enrollmentResult = await
    serviceClient.CreateOrUpdateIndividualEnrollmentAsync(enrollment)
      .ConfigureAwait(false);
}

查询 enrollmentResult.RegistrationState 将显示设备的注册状态。

向 IoT 中心流式处理数据

一旦设备成功注册,它就可以开始向 IoT 中心流式传输数据。IoT 中心支持用于数据引入的 HTTPS 和高级消息队列协议 (AMQP),并且它与格式无关,这意味着数据格式可以是任何形式,从 CS 到 JSON 再到 Avro(一个 Apache 数据序列化项目:avro.apache.org)。如果你正在设计来自远程位置的设备连接,而远程位置需要较小的代码占用空间或网络带宽有限,则可能需要考虑消息队列遥测传输 (MQTT: mqtt.org),即用于小型传感器和移动设备的轻量级消息传递协议,该协议已针对高延迟或不可靠的网络进行优化。不过,在设备到云的消息中有 256 K 的限制,这使得直接流式传输的数据无法用于捕获图像和语音数据。IoT 中心支持的另一种数据加载方法是将文件上传到 blob。摄像头首先在边缘(也就是设备本身)录制音频和视频,然后将这些数据上传到 IoT 中心。上传完成后,IoT 中心通过面向服务的终结点发出文件上传通知消息。然后,该事件触发授权流程,最终使用 ASP.NET Core 授权策略调用 Web API。需要注意的是,文件上传机制需要 Azure Blob 存储帐户。信息不是通过 IoT 中心本身来中转的。相反,IoT 中心充当到关联存储帐户的调度程序,因此在 Azure 中配置存储帐户并将其与 IoT 中心关联起来显然非常重要。有关详细说明,请参阅 bit.ly/2YOMz8Q

要初始化文件上传过程,设备以以下格式向 IoT 中心上的终结点发送 POST 请求:

{iot hub}.azure-devices.net/devices/{deviceId}/files

POST 请求包含此 JSON 正文:

{
  "blobName": "..."
}

IoT 中心返回 JSON 响应,设备使用它来上传文件:

{
  "correlationId": "<correlation_id>",
  "hostName": "<yourstorageaccount>.blob.core.windows.net",
  "containerName": "<container_name>",
  "blobName": "<blob_name>",
  "sasToken": "<token>"
}

上传完成后,设备发送会向以下对象发送 POST 请求:

{iot hub}.azure-devices.net/devices/{deviceId}/files/notifications

使用以下 JSON 正文:

{
  "correlationId": "<correlation ID received from the initial request>",
  "isSuccess": bool,
  "statusCode": XXX,
  "statusDescription": "Description of status"
}

如果你更喜欢 C#,可以通过从设备连接字符串中设置一个设备客户端来上传文件,然后将它作为一个流以异步方式发送给 blob:

async void SendToBlobAsync(string blobName, Stream stream)
{
  using (DeviceClient deviceClient =
    DeviceClient.CreateFromConnectionString(
      "<ConnectionString>", TransportType.Http1))
  {
    await deviceClient.UploadToBlobAsync(blobName, stream);
  }
}

入侵检测

目前为止描述的所有与数据相关的活动都发生在所谓的“暖路径存储”上,因为数据近乎是实时处理的。遥测数据还持久存档在 Azure Blob 存储中,以便进一步分析。这是 Azure 机器学习工作室作为数据源使用的“冷路径存储”,用于训练数据模型和检测未经授权的入侵。

若检测到的人员身份与访问通行证不一致,将立即阻止其进入场地。反之,流查看是否存在下面的任何异常,并继续操作:

  • 进入建筑的频率异常。
  • 此人之前是否曾进入此建筑(签出)。
  • 每日允许的访问次数。
  • 此人是否值班。
  • 建筑的关键性(可能无需限制对餐厅的访问,但要对服务器数据中心访问执行严格的策略)。
  • 此人是否带领其他人或携带其他物品同行。
  • 同一个建筑发生过的类似访问异常。
  • 过去评估的风险级别的变化。
  • 过去检测到的入侵次数。

Azure ML 运行异常检测服务,此服务返回评分来表示访问偏离标准值的可能性。使用 0 到 1 之间的数值表示此评分,其中 0 表示“未检测到风险”、一切正常、已受到完全信任;1 表示“红色警报”,要立即阻止进入!对于大于 0 的任意值,由各个建筑的风险级别决定用于允许进入建筑的可接受阈值。

入侵检测是一种异常情况检测问题,用于识别和预测群集中罕见或不寻常的数据点。ML 异常检测被广泛应用于检测潜在付款欺诈、捕获异常设备读数、发现网络入侵以及任何需要探测大量不可预测活动或元素的数据集的应用程序。

例如,对站点的访问可以随着时间的推移进行注册,并按不同条件(一天中的时间、一个人的角色、单独访问还是陪同访问、以前的访问等等)进行分组。这些条件被称为“特征”,并确定 ML 算法将验证的所有条件以评估入侵评分,包括是否为新访问,数据点是在平均记录值(群集)范围内还是范围外。如果数据点在范围之外,还会测量它与边界的距离(偏差),以将较低或较高的风险因素表示为介于 0 和 1 之间的数字(请参见图 4****)。

异常入侵表示形式
图 4 异常入侵表示形式

可能有数百个特征,每个特征在不同程度上都对入侵概率有贡献。安全主管认为,每个特征对入侵分数的贡献程度不是由一个人决定的,而是由作为模型训练一部分的 ML 流程推断出来的。因此,对于未经授权的建筑访问,如果使用他人通行证获得对建筑的访问被证明有很高的发生率,那么这种入侵类型的权重将是相同的。而且,如果这种做法减少,贡献级别就会同时降低。简单地说,这些模型无需显式编程就可以自学,例如通过手动检查。

通过分析数据来推断意义的过程被称为特征工程;在异常情况检测领域,你通常希望查看:

  • 聚合变量:例如,过去 24 小时、7 天或 30 天内每个位置的事务总数。
  • 不匹配值:用户的生物识别信息与访问通行证之间的任何不匹配,或检测到某人同时出现在多个地方,或者两个相距甚远的地方的时间差过短。
  • 风险表:按站点、对建筑的访问限制级别等分组的使用历史概率计算出的入侵风险。

Azure 机器学习工作室

Azure 机器学习工作室提供了一个可视化编辑器,用于从数据集开始构建 ML 试验,然后执行模型训练、评分和评估。接下来我们按顺序操作。图 5 显示了完整的 ML 流。

Azure 机器学习工作室中的站点入侵检测试验
图 5 Azure 机器学习工作室中的站点入侵检测试验

第一步是导入数据集。由于数据存储在 Azure Blob 中,Azure 机器学习工作室提供了一个名为“导入数据”的特定模块,可以使用该模块连接到 Azure Blob 服务。导入数据后,需要使用“拆分数据”模块将其分离为训练集和测试集。可以选择不同的拆分模式,具体取决于你拥有的数据类型以及你所需的拆分方式。在此解决方案中,我选择了“拆分行”选项,将数据分成两个随机部分,80% 的数据分配给训练数据集,其余数据用于测试。然后 ML 流对数据集执行训练。异常情况检测是一个分类问题,可以使用以下两种方法之一作为监督学习或无人监督学习执行:

  • 单类支持向量模型
  • 主成分分析

可以使用单类支持向量模型模块来创建异常情况检测模型,这对于数据主要是“正常”数据而没有你试图检测的许多异常情况的场景特别有用。例如,你可能需要检测欺诈性访问,但没有多少可以用来训练典型分类模型的欺诈性示例,但你可能有很多很好的示例。

相比之下,主成分分析(通常缩写为 PCA)是一项成熟的 ML 技术,可以在源数据集不为人知的情况下应用于探索性数据分析。PCA 揭示了数据的内部结构,并通过分析多个变量和可能的相关性以及最能捕捉结果差异的值的组合来解释数据中的方差。这些值被称为“主成分”,因为它们是影响结果的关键因素。

由于在此阶段无法预测哪种方法效果更好,因此我将使用这两种方法,并结合使用两个单独的训练异常情况检测模型模块,然后将互反结果与预测值评估进行比较。“评分模型”模块对经训练的模型进行评分预测,而“评估模型”,顾名思义,则使用标准指标,如准确性(分类模型的优劣性,即正确结果占总事例数的比例)、精准率(正确结果占所有阳性结果的比例)和召回率(模型返回的所有正确结果的比例)来评估分类模型的结果。指标得分较高的数据集将是生成与此训练实验相关联的预测服务的首选数据集。

Azure 机器学习工作室从预测实验生成 Web 服务,并将其公开为外部应用程序可以使用的 REST API。API 有一个驻留在 services.azureml.net 域中的终结点,这是你的服务所特有的。它需要使用在 HTTP 请求标头中作为 Authorization:Bearer 属性传递的 API 密钥进行身份验证。请求的内容类型是 application/json,请求正文采用 JSON 有效负载的形式,其中包含预测服务的输入值。服务输出也是一个带有评分值的 JSON 响应。图 6 中的 C# 代码显示了如何将 ML 服务与 HTTP 客户端结合使用。将请求构建为字符串数组集合之后,HTTP 客户端将使用请求标头授权属性中的 API 密钥初始化,并将其基本地址设置为 Web 服务的 URI。请求通过 POST 作为 JSON 消息以异步方式提交。

图 6 调用 Azure ML Web 服务

async Task InstrusionDetectionAsync()
{
  using (var client = new HttpClient())
  {
    var scoreRequest = new
    {
      Inputs = new Dictionary<string, StringTable>
      {
        ["input1"] = new StringTable
        {
          ColumnNames = new [] { "<Feature1>", "<Feature2>", "<Feature3>" },
          Values = new [,] { { "<Value1>", "<Value2>", "<Value3>" } }
        }
      }
    };
    client.DefaultRequestHeaders.Authorization =
      new AuthenticationHeaderValue("Bearer", "<ApiKey>");
    client.BaseAddress = new Uri("<EndpointURI>");
    HttpResponseMessage response = await client.PostAsJsonAsync("", scoreRequest);
    if (response.IsSuccessStatusCode)
    {
      string result = await response.Content.ReadAsStringAsync();
    }
  }
}
public class StringTable
{
  public string[] ColumnNames { get; set; }
  public string[,] Values { get; set; }
}

总结

Azure 云提供了丰富的资源工具集,通过正确的组合,可以帮助构建集成 IoT、机器学习、认知服务和 ASP.NET Core API 的端到端解决方案。这两篇文章的前一篇文章中描述的场景展示了 .NET Core 中用户授权的自定义策略框架的丰富性,它与用于识别生物特征(如人脸和声音)的识别服务的视觉和语音 API 协同工作。本文专注于从注册为 IoT 设备的摄像头收集此类生物识别信息,并将数据流式传输到 Azure 中的 IoT 中心。该解决方案包含一个 ML 服务,通过分析针对历史数据集的访问请求来支持授权过程,以检测潜在的未授权入侵。


Stefano Tempesta是 Microsoft 区域主管、人工智能和业务应用程序 MVP,以及 Blockchain Council 成员。作为国际 IT 会议的正式发言人(包括 Microsoft Ignite 和 Tech Summit),Tempesta 的关注点已延伸到区块链和与 AI 相关的技术。他创建了 Blogchain Space (blogchain.space)(一个关于区块链技术的博客),为 MSDN 杂志和 MS Dynamics World 撰写文章,并在 Azure AI 库 (gallery.azure.ai) 上发表机器学习实验。

衷心感谢以下 Microsoft 技术专家对本文的审阅:Danilo Diaz


在 MSDN 杂志论坛讨论这篇文章