question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] Microsoft.Azure.Services.AppAuthentication gives unusable access token

See original GitHub issue

Describe the bug

Unable to use MSI on net core 2.2 azure windows app service when using Microsoft.Azure.Services.AppAuthentication , whenever with the same configuration if i use bare MSI_ENDPOIND and MSI_SECRET in my code to get access token , the code starts working. Also if i omit setting access token completely the error message is changes(so library is doing something) The code giving me following problem

Exception or Stack Trace Exception message: Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. Stack trace:

at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at GraphQL.WebApi.Startup.<>c.<ConfigureServices>b__4_7(IServiceProvider serviceProvider) 

To Reproduce

i have tried to follow tutorial on setting up MSI to access data in Azure SQL Server Database First, i created app service and assigned system managed identity app-service Second i have created Azure AD Group and added system managed identity to a group sql group Then i connected to azure database right way™ and added Azure AD Group and granted it admin rights db_datareader db_datawriter db_ddladmin sql users Then i took a connection string from azure admin panel and modified it to be usable for MSI(see code below)

Then i tried to run code and it seems like it produces valid jwt token(checked under debugger) access token

And when i execute following command

use master;
SELECT *
FROM sys.event_log
where event_type = 'connection_failed'

on sql server im getting following result

testing	2019-07-12 18:30:00.0000000	2019-07-12 18:35:00.0000000	connectivity	connection_failed	4	login_failed_for_user	2	2	Login failed for user.

Code Snippet

var provider = new AzureServiceTokenProvider();
var token = provider.GetAccessTokenAsync("https://database.windows.net/", "xxxxxxxxx.onmicrosoft.com").Result;
 var sqlConnection = new SqlConnection("Data Source=xxxxx.database.windows.net;Initial Catalog=testing");
sqlConnection.AccessToken = token;
sqlConnection.Open()

Expected behavior The library should produce valid access token that can be understanded by Azure

Setup (please complete the following information):

  • OS: Windows(Azure App Service)
  • IDE : VS2019 (remote debugging)
  • Version of the Library used: (1.2.0 for net core)

Additional context Add any other context about the problem here.

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added

this issue if copied from https://github.com/dotnet/SqlClient/issues/138 because initially SqlClient library were under suspicion but it turned out it works just fine under net core and only token produced by AppAuthentication is not understood by Azure

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12

github_iconTop GitHub Comments

2reactions
rickvdboschcommented, Aug 19, 2019

UPDATE
I discussed this issue with some people, in the end a solution came up that works!

The main issue in my case was that my subscription (and my user) is a Microsoft account (Outlook). Because of this, you need to specify the tenantId in the GetAccessTokenAsync() call.

Apparently, for managed identities you do not have to specify the tenantId. With a user, it’s a good idea to explicitly specify it. In case of a personal MS account, specifying it is mandatory.

The steps I took to fix this issue:

  • I’ve created an Active Directory Group (let’s call it AdminGroup)
  • Both my user account and the Azure Function App’s Managed Identity are in AdminGroup
  • AdminGroup is set as the Active Directory Admin for the Azure SQL Server
  • I’ve created a database user AdminGroup in the database I want to connect to
  • I created a user for AdminGroup and added it to a role in the database, using:
CREATE USER [AdminGroup] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [AdminGroup];
ALTER ROLE db_datawriter ADD MEMBER [AdminGroup];
GO

My current code (sort of):

var tokenProvider = new AzureServiceTokenProvider();

using (var connection = new SqlConnection(CONNECTIONSTRING))
using (var command = new SqlCommand(QUERY, connection))
{
    connection.AccessToken = await tokenProvider.GetAccessTokenAsync("https://database.windows.net/", "<YOUR_TENANT_ID>");

    await connection.OpenAsync();
    var result = (await command.ExecuteScalarAsync()).ToString();

    return new OkObjectResult(result);
}

This solution has been tested and works both when specifying the tenantId (or Directory ID, the tenant’s GUID) and the ‘onmicrosoft’-name (xxx.onmicrosoft.com). It works in Azure and locally.

1reaction
loarabiacommented, Jul 26, 2019

Hi @IdeaHunter thanks for sending us the details about this issue. I’ve tagged this to try and get it routed to the right team.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Microsoft.Azure.Services.AppAuthentication unable to ...
Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. 'az' is not recognized as an internal or...
Read more >
Web app accesses SQL Database as the user - Azure ...
Next, you configure your App Service app to give you a usable access token. In the Cloud Shell, run the following commands on...
Read more >
Tutorial: Authenticate users E2E - Azure App Service
In this step, you configure App Service authentication and authorization to give you a usable access token for accessing the backend.
Read more >
Azure key vault - Microsoft Q&A
Exception Message: Tried to get token using Active Directory Integrated Authentication. Access token could not be acquired. Integrated Windows ...
Read more >
Azure authentication with Java and Azure Identity
This article provides an overview of the Java Azure Identity library, which provides Azure Active Directory token authentication support ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found