3

I have a WebAPI with ef6 code first setup and working. In app start we have dbmigrator.Update() which applies any pending migrations to database.

After changing the connection string to remove username and password and provide access token instead, dbmigrator.Update() fails with an error:

Login failed for user ''

How to ensure that dbmigrator works with Azure SQL access token instead of username/password in connection string?

Edit 1:

The change done to dbcontext constructor is to change it from

DbContext() : base("nameofConnString"){}

to

DbContext() : base(GetSQLConn(), true) 
{
     Database.SetInitializer<DbContext>(null);
}

With GetSQLConn(), I am retrieving a connection without uname/pwd and attaching accesstoken to it and returning the connection!

Edit 2:

    private static SqlConnection GetSQLConn()
    {
        var accessToken = TokenFactory.AcquireToken();
        var connString = ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;

        var conn = new SqlConnection(connString)
        {
            AccessToken = accessToken,
        };

        return conn;
    }
  • https://stackoverflow.com/questions/43130105/entity-framework-connection-to-sql-azure-db-using-access-token – Chetan Oct 01 '17 at 02:11
  • Yes Sir, I have gone through the link, and in fact that was the inspiration for me to go ahead with my change of using sql access token. But DbMigrator still fails. I would have requested for more info there, but I don't have enough reputation to comment on existing posts. – Newbie Programmer Oct 01 '17 at 02:16
  • Can you share the GetSQLConn method code? – Chetan Oct 01 '17 at 02:20
  • @ChetanRanpariya Added code used for GetSQLConn – Newbie Programmer Oct 01 '17 at 02:22
  • You have done other setup too such as AD integration and user creation etc. Mentioned in the link and other msdn links – Chetan Oct 01 '17 at 02:47
  • 1
    @ChetanRanpariya Yes, actually dbcontext works for CRUD operations on all my tables, just this migrator won't work! – Newbie Programmer Oct 01 '17 at 04:23

1 Answers1

0

How to ensure that dbmigrator works with Azure SQL access token instead of username/password in connection string?

actually dbcontext works for CRUD operations on all my tables, just this migrator won't work!

According to your comment, it seems that you have no permission to alert table. If you don't grant corresponding permission for the created user. Please have a try to grant permission to the created user. More details about db role please refer to the Database-Level Roles.

EXEC sp_addrolemember N'db_owner', N'your-user-name'

I also following the SO thread you mentioned.If I add the user to do_owner, I test it with Alter Table, it works correctly on my side. The following is my detail steps.

1.Registry an Azure AD Application

2.Provision an Azure Active Directory administrator for your Azure SQL server, more details please refer to the this tutorials

enter image description here

3.Create user for the Azure SQL and grant corresponding permission.

CREATE USER [RegistryAppName] FROM  EXTERNAL PROVIDER 

EXEC sp_addrolemember N'db_owner', 'RegistryAppName'

enter image description here

4.Change the demo code and run it as expected.

 SqlConnectionStringBuilder builder =
         new SqlConnectionStringBuilder
             {
               ["Data Source"] = "azureServername.database.windows.net",
                    ["Initial Catalog"] = "databaseName",
                    ["Connect Timeout"] = 30
             };
    // replace with your server name
    // replace with your database name

    string accessToken = TokenFactory.GetAccessToken();
    if (accessToken == null)
    {
         Console.WriteLine("Fail to acuire the token to the database.");
    }
    using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
    {
       try
          {
               connection.AccessToken = accessToken;
               connection.Open();

               var commentText = "ALTER TABLE AccountRec ADD newColumn varchar(10) ";
               SqlCommand sqlCommand = new SqlCommand(commentText, connection);
                   
               Console.WriteLine("Executed Result:" + sqlCommand.ExecuteNonQuery());
           }
         catch (Exception ex)
         {
                Console.WriteLine(ex.Message);
         }
      }
      Console.WriteLine("Please press any key to stop");
      Console.ReadKey();
Community
  • 1
  • 1
Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • 1
    All the steps listed are already performed and working. I have already mentioned database operations work with SQL query and dbcontext. The purpose of code first migration - DbMigrator is it starts with checking if database exists, by connecting to master database(The app is added to master database also and given a dbMabager role). Then goes down till latest migration to make sure database is up to date. This is something I would like to keep intact. – Newbie Programmer Oct 02 '17 at 10:37
  • 3
    This answer only tells me what I already know and I have done. I am specifically looking for a way to make Entity DbMigrator work with access token mechanism - which is not defined anywhere. – Newbie Programmer Oct 02 '17 at 10:46
  • What permission have you granted to the created user? – Tom Sun - MSFT Oct 02 '17 at 13:04
  • It is an app resource i created, It is granted db_owner for database, and at master database level in server, it is granted with db_manager. – Newbie Programmer Oct 02 '17 at 17:05
  • 1
    This problem is not about permissions for sure, I have gone through all public and private properties within dbMigrator and didn't see an access token within, I was only about to find the connection string without username/password. Hence my questions remains, how do I get the dbMIgrator to read the access token with the connection? – Newbie Programmer Oct 03 '17 at 01:01
  • I also can reproduce that on my side. It seems that it is not supported that by EF currently, maybe we could give [our idea](https://msdn.microsoft.com/en-us/library/hh913619(v=vs.113).aspx) to EF. – Tom Sun - MSFT Oct 06 '17 at 05:38