15

I am just trying to publish my application in Azure as a Web App. I have been facing issue about the connection string. The server just can't identify what the connection string is, as you may see from the error below:

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

Below is the 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"
    }
  }
}

And, here is the 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>();

If I run it from the local computer, using the same settings, it works fine. But, it does not work on the server. Any ideas?

UPDATE

When, I check from the url https://myapp.scm.azurewebsites.net/env, I see this section:

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

And, also this section, where the correct connection string is displayed:

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;
renakre
  • 8,001
  • 5
  • 46
  • 99
  • Looks like you are using Azure key vault for loading config settings which is failing: Check following: https://stackoverflow.com/questions/49027391/connection-to-azure-vault-using-msi – Mohsin Mehmood Aug 11 '19 at 14:27
  • @MohsinMehmood thanks for the reply! in the tutorial it talks about virtual machine which I am not using. I wonder if I should create it, or should I drop Azure key vauld? – renakre Aug 11 '19 at 14:44
  • You should keep using Azure key vault. But you need to enable managed identity. Check this article: https://learn.microsoft.com/en-us/azure/key-vault/tutorial-net-create-vault-azure-web-app – Mohsin Mehmood Aug 11 '19 at 14:51
  • @MohsinMehmood I did it, another error: `Unhandled Exception: Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Access denied. Caller was not found on any access policy.`. – renakre Aug 11 '19 at 15:01
  • @MohsinMehmood I had to do some configuration in AD but do not have permission. I guess I have to drop using key vault... – renakre Aug 11 '19 at 15:17
  • Have you tried to add access policy in your key vault for your web app? Based on my experience, it doesn't ask for aad admin role. – Jack Jia Aug 12 '19 at 02:18
  • 1
    Refer to this [thread](https://stackoverflow.com/questions/31097933/setting-the-sql-connection-string-for-asp-net-core-web-app-in-azure) to set the sql connection string for webapp in azure. – Joey Cai Aug 12 '19 at 03:17
  • You should probably regen the key to your storage account if you haven't since posting it on the internet. – BenV May 13 '20 at 20:35
  • @Mohsin Mehmood : what about the code indicates keyvault use? Or maybe you mean the error message indicates keyvault use? – steve Oct 02 '20 at 21:34

3 Answers3

17

For me this happen when i run my function app locally and i change my Microsoft password, as the logged in user credentials were using for authorizations for managed identity, Try re entering your credentials

Heshan
  • 772
  • 8
  • 22
10

Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net

The error actually happens when the AzureServiceTokenProvider is trying to obtain a token to access the Vault using the service’s Managed Identity.

1.Pass “RunAs=App;” in the connectionString parameter of AzureServiceTokenProvider. This way it will not try different modes to obtain a token, and the exception is a bit better.

2.Install/update the latest version of Microsoft.Azure.Services.AppAuthentication.

When you enable MSI and get access denied, check Azure keyvault Access policy>add access policy and add your MSI service principle with get secret permission. Refer to this article.

Joey Cai
  • 18,968
  • 1
  • 20
  • 30
  • 2
    FWIW: I didn't know what MSI meant, but after some reading it seems to mean Managed Service Identity ... which is now an old name ... new name is managed identity for azure resource or something like that. – steve Oct 05 '20 at 19:14
  • Simply updating the version of `Microsoft.Azure.Services.AppAuthentication` from 1.5.0 to 1.6.2 fixed the issue for me – seandkim Jun 26 '22 at 21:30
7

I know this has an accepted answer, but it didn't help much with my keyvault issue, which had the same error message, so posting a new answer here just in case it helps someone stumbles upon this question.

My app was connecting fine locally, but failing on remote, issue is it needed an identity and be allowed access to the key vault.

Refer to this with more details steps on how to setup that Azure web app and managed identity to access key vault

Mocas
  • 1,403
  • 13
  • 20
  • I was having a similar issue: app connected locally, but failed with a generic 500 error when trying to access an Azure DataFactory. The local-running app was granted access via my dev identity. The solution (built off the link @Mocas shared) was to give my app a System Managed Identity, then grant that identity a contributor role within the DataFactory. – Cosmo Hidalgo Jul 13 '23 at 14:48