Azure Web 应用程序无法找到连接字符串。

16

我只是试图将我的应用程序作为Web应用程序发布到Azure。 我一直在处理有关连接字符串的问题。 正如您从下面的错误中看到的那样,服务器无法识别连接字符串:

Unhandled Exception: Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/b99992c6-d6c5-4028-99b5-a1f106bb90bc. Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/b99992c6-d6c5-4028-99b5-a1f106bb90bc. Exception Message: Tried to get token using Managed Service Identity. Access token could not be acquired. An attempt was made to access a socket in a way forbidden by its access permissions
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/b99992c6-d6c5-4028-99b5-a1f106bb90bc. Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Visual Studio Token provider file not found at "D:\local\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json"
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/b99992c6-d6c5-4028-99b5-a1f106bb90bc. Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. 'az' is not recognized as an internal or external command,
operable program or batch file.

   at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.GetAuthResultAsyncImpl(String authority, String resource, String scope, CancellationToken cancellationToken)
   at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.<get_KeyVaultTokenCallback>b__8_0(String authority, String resource, String scope)
   at Microsoft.Azure.KeyVault.KeyVaultCredential.PostAuthenticate(HttpResponseMessage response)
   at Microsoft.Azure.KeyVault.KeyVaultCredential.ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Azure.KeyVault.KeyVaultClient.GetSecretsWithHttpMessagesAsync(String vaultBaseUrl, Nullable`1 maxresults, Dictionary`2 customHeaders, CancellationToken cancellationToken)
   at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.GetSecretsAsync(IKeyVaultClient operations, String vaultBaseUrl, Nullable`1 maxresults, CancellationToken cancellationToken)
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.LoadAsync()
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at Synergy.Program.Main(String[] args) in C:\Users\Erkan Er\source\repos\Synergy\Program.cs:line 21

以下是 appsettings.json 文件:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=server.database.windows.net;Initial Catalog=synergylearn_db;User ID=userid;Password=password;Connect Timeout=60;Encrypt=True;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;RunAs=App;",
    "AzureStorageConnectionString-1": "DefaultEndpointsProtocol=https;AccountName=encamina;AccountKey=V0/+NhCGcq1vBCc1wJ5L9V620fi5E0cX0cX4/pbOFzjqBxRapLBmaDt75LQcoX3HBskY/34E0MwGH/OWToryUg==;EndpointSuffix=core.windows.net"
  },
  "AppSettings": {
    "Secret": "abc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Authentication": {
    "Google": {
      "ClientId": "xxx",
      "ClientSecret": "xx"
    }
  }
}

这里是 Startup.cs:

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => {
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            }); ;


        // configure strongly typed settings objects
        var appSettingsSection = Configuration.GetSection("AppSettings");
        services.Configure<AppSettings>(appSettingsSection);

        // configure jwt authentication
        var appSettings = appSettingsSection.Get<AppSettings>();
        var key = Encoding.ASCII.GetBytes(appSettings.Secret);
        services.AddAuthentication(x =>
        {
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        });

        services.AddDbContext<SynergyDbContext>( 
           options => options.UseSqlServer(
               Configuration.GetConnectionString("DefaultConnection")
               //Configuration["ConnectionStrings:DefaultConnection"]
               )
           );
        services.AddTransient<SynergyDbContext>();

如果我在本地计算机上使用相同的设置运行它,则可以正常工作。但是,在服务器上无法工作。有什么建议吗?

更新

当我从网址https://myapp.scm.azurewebsites.net/env检查时,我看到了这个部分:

Connection Strings
LocalSqlServer
ConnectionString = data source=.\SQLEXPRESS;Integrated 
Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true
ProviderName = System.Data.SqlClient

同时,这一部分显示了正确的连接字符串:

SQLCONNSTR_DefaultConnection = Data Source=server.database.windows.net;Initial Catalog=synergylearn_db;User ID=userid;Password=password;Connect Timeout=60;Encrypt=True;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;RunAs=App;

看起来您正在使用 Azure 密钥保管库加载配置设置,但出现了故障:请检查以下内容: https://dev59.com/bKnka4cB1Zd3GeqPNmrY - Mohsin Mehmood
你应该继续使用Azure密钥保管库,但需要启用托管标识。请查看此文章:https://learn.microsoft.com/en-us/azure/key-vault/tutorial-net-create-vault-azure-web-app - Mohsin Mehmood
@MohsinMehmood,我做到了,但又出现了一个错误:Unhandled Exception: Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Access denied. Caller was not found on any access policy. - renakre
@MohsinMehmood 我需要在AD中进行一些配置,但是没有权限。我想我必须放弃使用密钥保管库... - renakre
1
请参考此帖子,为Azure中的Web应用程序设置SQL连接字符串。 - Joey Cai
显示剩余4条评论
3个回答

18

当我在本地运行我的函数应用并更改我的 Microsoft 密码时,这种情况就发生了, 因为登录的用户凭据被用于托管标识的授权, 请尝试重新输入您的凭据。


7
这对我来说就是这样了。请检查您是否需要在Visual Studio中重新输入您的凭据,分别在“帮助”>“关于”>“许可证状态”和“工具”>“选项”>“Azure服务身份验证”下进行检查。 - ovinophile
非常高兴!!! - Yster

10

Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: 参数:连接字符串:[未指定连接字符串],资源:https://vault.azure.net

实际上,当AzureServiceTokenProvider尝试使用服务的托管标识获取访问Vault的令牌时,会发生此错误。

1.在AzureServiceTokenProvider的connectionString参数中传递“RunAs=App;”,这样它将不会尝试不同的模式来获取令牌,并且异常信息会更好一些。

2.安装/更新最新版本的Microsoft.Azure.Services.AppAuthentication

当启用MSI并出现访问被拒绝时,请检查Azure Key Vault访问策略>添加访问策略,并添加您的MSI服务主体以获得获取密钥权限。请参阅此文章


2
说实话,我不知道 MSI 是什么意思,但是经过一些阅读后,似乎它的意思是托管服务标识......现在已经是一个老名称了......新名称是 Azure 资源托管标识或者类似的东西。 - steve
仅仅将 Microsoft.Azure.Services.AppAuthentication 的版本从1.5.0更新到1.6.2就解决了我的问题。 - seandkim

7

我知道这里有一个已被接受的答案,但它并没有对我的密钥保管库问题提供太多帮助,而我的问题与此错误消息相同,因此在此发布一个新答案,以防它能够帮助到某个人。

我的应用程序在本地连接良好,但在远程连接时失败了,问题在于它需要身份验证并被允许访问密钥保管库。

请参考Azure Web App和托管标识以访问密钥保管库 的详细步骤来设置。


我遇到了类似的问题:应用程序在本地连接正常,但在尝试访问 Azure DataFactory 时出现了一个通用的 500 错误。本地运行的应用程序已通过我的开发身份获得了访问权限。解决方案(基于 @Mocas 分享的链接)是为我的应用程序提供一个系统托管的身份,然后在 DataFactory 中授予该身份一个贡献者角色。 - Cosmo Hidalgo
我遇到了类似的问题:应用程序在本地连接正常,但在尝试访问Azure DataFactory时出现了一个通用的500错误。本地运行的应用程序已通过我的开发者身份获得了访问权限。解决方案(基于@Mocas分享的链接)是为我的应用程序提供一个系统托管的身份,然后在DataFactory中授予该身份一个贡献者角色。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接