Home > Net >  Connecting C# Azure Function with Azure SQL using User-Managed Identity. Authentication Failed
Connecting C# Azure Function with Azure SQL using User-Managed Identity. Authentication Failed

Time:11-14

I am Currently working on Azure Function with Azure SQL connection. The Azure SQL Server was mapped with User Managed Identity. When I connecting the Azure SQL server with Azure Functions in C# I am facing Authentication Issues. Please find the issue below.

"Microsoft.Data.SqlClient.SqlException (0x80131904): ManagedIdentityCredential authentication failed: Service request failed.\r\nStatus: 400 (Bad Request)\r\n\r\nContent:\r\n\r\n\r\nHeaders:\r\nDate: Thu, 10 Nov 2022 11:59:51 GMT\r\nServer: Kestrel\r\nTransfer-Encoding: chunked\r\nX-CORRELATION-ID: REDACTED\r\nContent-Type: application/json; charset=utf-8\r\n\nSee the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/managedidentitycredential/troubleshoot\r\n ---> Azure.Identity.AuthenticationFailedException: ManagedIdentityCredential authentication failed: Service request failed.\r\nStatus: 400 (Bad Request)\r\n\r\nContent:\r\n\r\n\r\nHeaders:\r\nDate: Thu, 10 Nov 2022 11:59:51 GMT\r\nServer: Kestrel\r\nTransfer-Encoding: chunked\r\nX-CORRELATION-ID: REDACTED\r\nContent-Type: application/json; charset=utf-8\r\n\nSee the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/managedidentitycredential/troubleshoot\r\n ---> Azure.RequestFailedException: Service request failed.\r\nStatus: 400 (Bad Request)\r\n\r\nContent:\r\n\r\n\r\nHeaders:\r\nDate: Thu, 10 Nov 2022 11:59:51 GMT\r\nServer: Kestrel\r\nTransfer-Encoding: chunked\r\nX-CORRELATION-ID: REDACTED\r\nContent-Type: application/json; charset=utf-8\r\n\r\n   at Azure.Identity.ManagedIdentitySource.HandleResponseAsync(Boolean async, TokenRequestContext context, Response response, CancellationToken cancellationToken)\r\n   at Azure.Identity.ManagedIdentitySource.AuthenticateAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)\r\n   at Azure.Identity.ManagedIdentityClient.AuthenticateAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)\r\n   at Azure.Identity.ManagedIdentityCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)\r\n   --- End of inner exception stack trace ---\r\n   at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex, String additionalMessage)\r\n   at Azure.Identity.ManagedIdentityCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)\r\n   at Azure.Identity.ManagedIdentityCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)\r\n   at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.AcquireTokenAsync(SqlAuthenticationParameters parameters)\r\n   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.<>c__DisplayClass147_1.<<GetFedAuthToken>b__1>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.GetFedAuthToken(SqlFedAuthInfo fedAuthInfo)\r\n   at Microsoft.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)\r\n   at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)\r\n   at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)\r\n   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)\r\n   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)\r\n   at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)\r\n   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)\r\n   at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)\r\n   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)\r\n   at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)\r\n   at SampleFunction.Repository.TaskRepository.GetData() in C:\\Users\\vinothkumar.sivaram\\Downloads\\SampleFunction12\\SampleFunction\\SampleFunction\\Repository\\TaskRepository.cs:line 38\r\nClientConnectionId:bc712cd9-cff0-4296-b273-3253088258cd",

Pleas find the sample code of mine

Function

 [FunctionName("GetItems")]
        public async Task<IActionResult> GetItems(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            var TaskData = _repository.GetData();
                       
            return new OkObjectResult(TaskData);
        }

SQL Helper Class

        public async Task<List<TaskModel>> GetData()
        {
            List<TaskModel> taskList = new List<TaskModel>();

                using (SqlConnection connection = new SqlConnection(Environment.GetEnvironmentVariable("SqlConnectionString")))
                {

                connection.Open();
                {
                    //
                }

                }

            return taskList;
        }

Connection String

"SqlConnectionString": "Server=tcp:dbserver.database.windows.net,1433;Initial Catalog=db;Authentication = Active Directory Managed Identity;

Please find the Steps of Azure Identity

Step 1 - identity

Step 2 - Identity Assign for SQLServer

Also I have assigned Role and Access control to my user ID.

But still I am facing ManagedIdentity Authentication issue.

Specially I don't want to use the Azure Key Vault. Need to use Managed Identity and Active Directory Managed Identity in Connection string

CodePudding user response:

Connecting C# Azure Function with Azure SQL using User-Managed Identity. Authentication Failed

Normally, the Connection String varies based on the type of authentication where User ID and Authentication Values will be varied.

enter image description here

As @Scott Mildenberger suggested that MS Doc that states to add the attribute User Id=ClientIdOfManagedIdentity in the Connection String of Database Server when specifying the application configuration settings.

In your case also, Authentication and UserId values are set to be Active Directory Managed Identity and ClientIdOfManagedIdentity and then it has to be deployed to reflect the changes and work.

  • Related