You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure环境下通过PowerShell对接SQL DB的许可验证架构咨询

架构实现方案推荐与步骤

优先选型:Azure Function(PowerShell运行时)

完全匹配你的技术栈,不用切换到C#/ASP.NET,用熟悉的PowerShell就能开发中间层服务,同时满足安全隔离SQL DB、按需扩缩容的需求,适合当前客户规模。

具体实现步骤

  • 创建并配置Azure Function App

    1. 在Azure门户创建Function App,运行时选择PowerShell 7.x,托管计划选「消耗计划」(成本低,适合小流量)。
    2. 配置网络隔离:将Function App加入与Azure SQL DB同VNet的子网,或者在SQL DB防火墙规则中添加Function App的出站IP地址,确保Function能安全访问SQL DB,同时SQL DB不暴露公网。
    3. 在Function App的「应用设置」中添加SQL DB连接字符串,命名为SqlConnectionString,后续函数直接读取这个配置,避免硬编码敏感信息。
  • 编写PowerShell函数处理查询请求
    创建一个HTTP触发的Function,核心逻辑如下:

    using namespace System.Net
    
    # 输入参数:HTTP请求对象
    param($Request, $TriggerMetadata)
    
    # 获取请求中的客户ID参数
    $customerId = $Request.Query.CustomerId
    if (-not $customerId) {
        Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
            StatusCode = [HttpStatusCode]::BadRequest
            Body = "缺少必填参数CustomerId"
        })
        return
    }
    
    # 严格校验客户ID格式(防止SQL注入,比如限制为字母数字组合)
    if ($customerId -notmatch '^[a-zA-Z0-9]+$') {
        Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
            StatusCode = [HttpStatusCode]::BadRequest
            Body = "CustomerId格式不合法"
        })
        return
    }
    
    try {
        # 加载SqlServer模块(需在Function App的requirements.psd1中添加SqlServer依赖)
        Import-Module SqlServer
    
        # 从应用设置读取连接字符串
        $connString = $env:SqlConnectionString
    
        # 动态构造查询语句(注意:这里用引号包裹表名,同时已校验ID格式,降低注入风险)
        $query = @"
            SELECT * FROM [$customerId] 
            JOIN 主表 ON [$customerId].CustomerId = 主表.CustomerId
            WHERE [$customerId].CustomerId = '$customerId'
        "@
    
        # 执行查询并获取结果
        $licenseInfo = Invoke-SqlCmd -ConnectionString $connString -Query $query
    
        # 返回许可信息
        Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
            StatusCode = [HttpStatusCode]::OK
            Body = $licenseInfo | ConvertTo-Json
        })
    }
    catch {
        Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
            StatusCode = [HttpStatusCode]::InternalServerError
            Body = "查询失败:$($_.Exception.Message)"
        })
    }
    

    同时在Function的requirements.psd1中添加SqlServer模块依赖:

    @{
        'SqlServer' = '22.1.1'
    }
    
  • 配置函数身份验证
    关闭Function的匿名访问,选择「Function Key」或「Azure AD身份验证」:

    • 用Function Key的话,客户调用时需要在请求头或URL中带上code参数;
    • 用Azure AD的话,客户需获取AD令牌再调用,安全性更高。
  • 客户侧PowerShell调用示例
    客户服务器上的服务可以用以下代码查询许可:

    $functionUrl = "https://你的FunctionApp名称.azurewebsites.net/api/你的Function名称"
    $functionKey = "你的Function密钥"
    $customerId = "客户的唯一ID"
    
    $params = @{
        Uri = $functionUrl
        Headers = @{ 'x-functions-key' = $functionKey }
        Method = "GET"
        Body = @{ CustomerId = $customerId } | ConvertTo-Json
        ContentType = "application/json"
    }
    
    try {
        $response = Invoke-RestMethod @params
        # 根据返回的许可信息判断是否继续运行
        if ($response.过期日期 -gt (Get-Date)) {
            # 许可有效,继续运行服务
            Write-Host "许可有效"
        } else {
            # 许可过期,停止服务
            Write-Host "许可已过期"
        }
    }
    catch {
        Write-Host "查询许可失败:$($_.Exception.Message)"
    }
    

数据库设计优化建议

当前客户规模不大的情况下,不建议为每个客户创建独立表,改用单表+CustomerId字段的设计更易维护,比如一张Licenses表包含所有客户的许可信息,查询时直接按CustomerId过滤,能大幅降低SQL注入风险和数据库维护成本。如果坚持分表,务必严格校验CustomerId的格式,避免恶意构造表名引发注入。

安全强化要点

  • 用Azure Managed Identity代替连接字符串中的用户名密码:为Function App启用系统分配的托管身份,在SQL DB中为该身份授予查询权限,彻底避免敏感凭证泄露。
  • 限制Function的HTTP触发端点仅允许客户的公网IP访问,在Function App的防火墙规则中配置IP白名单。

内容的提问来源于stack exchange,提问作者LukeFFP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:05:18