【问题标题】:Isolated Azure Function Managed Identity for SQL Server Auth用于 SQL Server 身份验证的独立 Azure 函数托管标识
【发布时间】:2021-06-09 14:37:56
【问题描述】:

我有一个 .NET 5 Azure Function 运行,FUNCTIONS_WORKER_RUNTIME 配置值为 dotnet-isolated

函数应用需要使用 EF Core 5.0.6 连接到 Azure SQL 数据库。

我遵循this post 的指导进行 EF 配置。

我的自定义 dbcontext 现在是:

public class SmsOrderContext : DbContext
{
    private readonly AzureServiceTokenProvider azureServiceTokenProvider;

    public SmsOrderContext(DbContextOptions<SmsOrderContext> options, AzureServiceTokenProvider azureServiceTokenProvider) : base(options)
    {
        RelationalDatabaseCreator databaseCreator =
                    (RelationalDatabaseCreator)this.Database.GetService<IDatabaseCreator>();
        databaseCreator.EnsureCreated();
        this.azureServiceTokenProvider = azureServiceTokenProvider;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        SqlConnection connection = new SqlConnection();
        string? envConString = Environment.GetEnvironmentVariable(ConfigConstants.SqlSvrConnString);
        connection.ConnectionString = envConString ?? "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SmsRouter";
        if (azureServiceTokenProvider != null)
            connection.AccessToken = azureServiceTokenProvider.GetAccessTokenAsync("https://database.windows.net/").Result;
        optionsBuilder.UseSqlServer(connection);
    }
}

检查SqlSvrConnString 环境变量的条件在那里,以便我可以在本地运行应用程序 - 它使用 localdb(这工作正常)而不是 Azure

在 program.main 我有:

.ConfigureServices(s =>
{
    s.AddSingleton<AzureServiceTokenProvider>(new AzureServiceTokenProvider());
    s.AddDbContext<SmsOrderContext>();
}

在我的函数应用上,Identity\System 分配的“状态”切换设置为“开启”

当我触发 Azure 函数(来自 http 请求)时,我在 Application Insights 中看到以下异常:

失败异常:Microsoft.Data.SqlClient.SqlException (0x80131904):
用户“”登录失败

我认为这表明身份没有被传递给 Sql Server?谁能看看我哪里出错了?

【问题讨论】:

标签: entity-framework-core azure-functions azure-web-app-service


【解决方案1】:

如果您想使用 Azure MSI 访问 Azure SQL,请参考以下步骤

  1. 启用微星

  2. 创建 Azure AD 组

Connect-AzureAD
New-AzureADGroup -DisplayName "My new group" -MailEnabled $false -SecurityEnabled $true -MailNickName "NotSet"
  1. 将 MSI 添加为组成员
Add-AzureADGroupMember -ObjectId "the id of the group" -RefObjectId "the id of the msi"
  1. 将组设置为 SQL server Azure AD admin

  2. 代码

我的DbContext

using Microsoft.EntityFrameworkCore;
using Microsoft.Data.SqlClient;
using Microsoft.Azure.Services.AppAuthentication;
namespace httpfun{

   public class BloggingContext : DbContext
        {
           private readonly AzureServiceTokenProvider azureServiceTokenProvider;

    public BloggingContext(DbContextOptions<BloggingContext> options, AzureServiceTokenProvider azureServiceTokenProvider) : base(options)
    {
       
        this.azureServiceTokenProvider = azureServiceTokenProvider;
    }
            public DbSet<Blog> Blogs { get; set; }
             

        protected override void OnConfiguring(DbContextOptionsBuilder options)
          {
            SqlConnection connection= new SqlConnection();
            connection.ConnectionString="Server=tcp:<>database.windows.net,1433;Database=<>;";
            connection.AccessToken = azureServiceTokenProvider.GetAccessTokenAsync("https://database.windows.net/").Result;
            options.UseSqlServer(connection);
          }
         }

        public class Blog
        {
            public int BlogId { get; set; }
            public string Url { get; set; }

            
        }

}

我的Program.cs

using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker.Configuration;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;

namespace httpfun
{
    public class Program
    {
        public static void Main()
        {
            var host = new HostBuilder()
                .ConfigureFunctionsWorkerDefaults()
                .ConfigureServices(services=>{
                    services.AddSingleton<AzureServiceTokenProvider>(new AzureServiceTokenProvider());
                    services.AddDbContext<BloggingContext>();
                    
                })
                .Build();

            host.Run();
        }
    }
}

我的函数代码(我使用 HTTP 触发器进行测试)

using System.Collections.Generic;
using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace httpfun
{
    public  class HttpTrigger1
    {
        private   readonly  BloggingContext _context;

        public HttpTrigger1(BloggingContext context){
               this._context=context;
        }

        [Function("HttpTrigger1")]
        public  HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
            FunctionContext executionContext)
        {
            var logger = executionContext.GetLogger("HttpTrigger1");
            logger.LogInformation("C# HTTP trigger function processed a request.");

            
                logger.LogInformation("Inserting a new blog");
                _context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/adonet" });
                _context.SaveChanges();
            

            var response = req.CreateResponse(HttpStatusCode.OK);
            response.Headers.Add("Content-Type", "text/plain; charset=utf-8");

            response.WriteString("Welcome to Azure Functions!");

            return response;
        }
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 2021-09-01
  • 2019-09-08
  • 2021-10-30
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
相关资源
最近更新 更多