EF6 with AAD auth works locally, but not on deployed app in Azure

200 Views Asked by At

I'm working on an .Net 4.8 app using EF6. A decission was made to use AAD authentication so we've implemented usage of Microsoft.Data.SqlClient using ErikEJs ErikEJ.EntityFramework.SqlServer library.

The apps DBContext initially inherited Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext<TUser> which internally uses System.Data.SqlClient. To get rid of this I've moved the model creation and more from this base class into the apps DBContext trying to avoid the usage of System.Data.SqlClient.

public class ApplicationDbContext : DbContext 
{
   public ApplicationDbContext() : base("DefaultConnection")
   {} 

   //Identity 
   public virtual IDbSet<ApplicationUser> Users { get; set; } 
   public virtual IDbSet<IdentityRole> Roles { get; set; } 
   public bool RequireUniqueEmail { get; set; }

    //Other models...
    public virtual DbSet<LogEntry> LogEntries { get; set; }
    public virtual DbSet<Form> Forms { get; set; }
    .....
}

I've configured entity framework in web.config as documented.

<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="DefaultConnection" providerName="Microsoft.Data.SqlClient" connectionString="Server=tcp:someserver.database.windows.net;Authentication=Active Directory Default;Encrypt=False;TrustServerCertificate=True;Database=our_database;" />
  </connectionStrings>
  <entityFramework>
    <providers>      
      <provider invariantName="Microsoft.Data.SqlClient" type="System.Data.Entity.SqlServer.MicrosoftSqlProviderServices, ErikEJ.EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SqlClient"/>
      <add name="SqlClient Data Provider"
        invariant="Microsoft.Data.SqlClient"
        description=".NET Framework Data Provider for SqlServer"
        type="Microsoft.Data.SqlClient.SqlClientFactory, Microsoft.Data.SqlClient" />
    </DbProviderFactories>
  </system.data>
  .
  .  
<configuration>  

I've tested the app localy connecting to the azure database. The dbcontext is able to connect to the database and works as expceted. But when we deploy the app to Azure, the dbcontext is unable to connect to the database resulting in an exception with the message "Invalid value for key 'authentication'. To verify that the app is actually able to connect to the database, I've implemented a healthcheck doing a 'Select 1' on the database. And this works.

The stacktrace indicates that the deployed app still uses System.Data.SqlClient in the dbcontext for some strange reason.

at System.Data.Common.DbConnectionStringBuilderUtil.ConvertToAuthenticationType(String keyword, Object value)
   at System.Data.SqlClient.SqlConnectionString.ConvertValueToAuthenticationType()
   at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
   at System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
   at System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.SetConnectionString(DbConnection connection, DbConnectionPropertyInterceptionContext`1 interceptionContext)
   at System.Data.Entity.Internal.LazyInternalConnection.TryInitializeFromAppConfig(String name, AppConfig config)
   at System.Data.Entity.Internal.LazyInternalConnection.Initialize()
   at System.Data.Entity.Internal.LazyInternalConnection.get_Connection()
   at Myapp.HealthChecks.HealthCheckImpls.DatabaseEntityFrameworkHealthCheck.CheckStatus() in C:\dev\TeamCity\buildAgent\work\9a6b8feb000b85a8\Myapp\Services\HealthChecks\HealthCheckImpls\DatabaseEntityFrameworkHealthCheck.cs:line 23

I've checked that the web.config corresponds with the one I am using locally. Code based configuration has also been tested without success regarding this issue.

0

There are 0 best solutions below