【问题标题】:Active Directory Interactive authentication in ASP.NET Core Razor Pages Web App not working when deployed to Azure App ServiceASP.NET Core Razor Pages Web App 中的 Active Directory 交互式身份验证在部署到 Azure 应用服务时不起作用
【发布时间】:2022-01-06 07:42:41
【问题描述】:

我有一个用于与 Azure SQL 数据库交互的网络应用程序。它按预期工作,但是当我从使用 SQL 用户/传递连接字符串更改为使用 Active Directory Interactive 时,当网络应用程序提示登录时出现错误。

请注意,这只发生在应用作为 Azure 应用服务发布时,它在本地按预期工作。

我没有经验,所以我很难理解错误。

下面是我的连接字符串。

"Connection1": "Server=xxx.database.windows.net; Initial Catalog=xxx; Authentication=Active Directory Interactive;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"

这是当用户在开发模式下加载新页面时使用连接字符串时收到的错误。

老实说,我对此感到不知所措。这似乎是某种机器配置问题,我不知道从哪里开始。

任何建议表示赞赏!堆栈如下:

System.AggregateException: One or more errors occurred. (One or more errors occurred. (An HttpListenerException occurred while listening on http://localhost:56718/ for the system browser to complete the login. Possible cause and mitigation: the app is unable to listen on the specified URL; run 'netsh http add iplisten 127.0.0.1' from the Admin command prompt.))
 ---> System.AggregateException: One or more errors occurred. (An HttpListenerException occurred while listening on http://localhost:56718/ for the system browser to complete the login. Possible cause and mitigation: the app is unable to listen on the specified URL; run 'netsh http add iplisten 127.0.0.1' from the Admin command prompt.)
 ---> MSAL.NetCore.4.39.0.0.MsalClientException: 
    ErrorCode: http_listener_error
Microsoft.Identity.Client.MsalClientException: An HttpListenerException occurred while listening on http://localhost:56718/ for the system browser to complete the login. Possible cause and mitigation: the app is unable to listen on the specified URL; run 'netsh http add iplisten 127.0.0.1' from the Admin command prompt.
 ---> System.Net.HttpListenerException (5): Access is denied.
   at System.Net.HttpListener.SetupV2Config()
   at System.Net.HttpListener.Start()
   at Microsoft.Identity.Client.Platforms.Shared.DefaultOSBrowser.HttpListenerInterceptor.ListenToSingleRequestAndRespondAsync(Int32 port, String path, Func`2 responseProducer, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at Microsoft.Identity.Client.Platforms.Shared.DefaultOSBrowser.HttpListenerInterceptor.ListenToSingleRequestAndRespondAsync(Int32 port, String path, Func`2 responseProducer, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Platforms.Shared.Desktop.OsBrowser.DefaultOsBrowserWebUi.InterceptAuthorizationUriAsync(Uri authorizationUri, Uri redirectUri, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Platforms.Shared.Desktop.OsBrowser.DefaultOsBrowserWebUi.AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.FetchAuthCodeAndPkceInternalAsync(IWebUI webUi, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.FetchAuthCodeAndPkceVerifierAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.GetTokenResponseAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenInteractiveParameters interactiveParameters, CancellationToken cancellationToken)
   at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.AcquireTokenInteractiveDeviceFlowAsync(IPublicClientApplication app, String[] scopes, Guid connectionId, String userId, SqlAuthenticationMethod authenticationMethod)
   at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.<>c__DisplayClass17_0.<<AcquireTokenAsync>b__0>d.MoveNext()
Inner Exception: System.Net.HttpListenerException (5): Access is denied.
   at System.Net.HttpListener.SetupV2Config()
   at System.Net.HttpListener.Start()
   at Microsoft.Identity.Client.Platforms.Shared.DefaultOSBrowser.HttpListenerInterceptor.ListenToSingleRequestAndRespondAsync(Int32 port, String path, Func`2 responseProducer, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.<>c__DisplayClass146_1.<GetFedAuthToken>b__1()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__271_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of inner exception stack trace ---
   at Microsoft.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)
   at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at xxx.Pages.xxx.IndexModel.OnGetAsync() in C:\Users\xxx\source\repos\xxx\xxx\Pages\xxx\Index.cshtml.cs:line 37
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
MSAL.NetCore.4.39.0.0.MsalClientException: 
    ErrorCode: http_listener_error
Microsoft.Identity.Client.MsalClientException: An HttpListenerException occurred while listening on http://localhost:56718/ for the system browser to complete the login. Possible cause and mitigation: the app is unable to listen on the specified URL; run 'netsh http add iplisten 127.0.0.1' from the Admin command prompt.
 ---> System.Net.HttpListenerException (5): Access is denied.
   at System.Net.HttpListener.SetupV2Config()
   at System.Net.HttpListener.Start()
   at Microsoft.Identity.Client.Platforms.Shared.DefaultOSBrowser.HttpListenerInterceptor.ListenToSingleRequestAndRespondAsync(Int32 port, String path, Func`2 responseProducer, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at Microsoft.Identity.Client.Platforms.Shared.DefaultOSBrowser.HttpListenerInterceptor.ListenToSingleRequestAndRespondAsync(Int32 port, String path, Func`2 responseProducer, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Platforms.Shared.Desktop.OsBrowser.DefaultOsBrowserWebUi.InterceptAuthorizationUriAsync(Uri authorizationUri, Uri redirectUri, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Platforms.Shared.Desktop.OsBrowser.DefaultOsBrowserWebUi.AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.FetchAuthCodeAndPkceInternalAsync(IWebUI webUi, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.FetchAuthCodeAndPkceVerifierAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.GetTokenResponseAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenInteractiveParameters interactiveParameters, CancellationToken cancellationToken)
   at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.AcquireTokenInteractiveDeviceFlowAsync(IPublicClientApplication app, String[] scopes, Guid connectionId, String userId, SqlAuthenticationMethod authenticationMethod)
   at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.<>c__DisplayClass17_0.<<AcquireTokenAsync>b__0>d.MoveNext()
Inner Exception: System.Net.HttpListenerException (5): Access is denied.
   at System.Net.HttpListener.SetupV2Config()
   at System.Net.HttpListener.Start()
   at Microsoft.Identity.Client.Platforms.Shared.DefaultOSBrowser.HttpListenerInterceptor.ListenToSingleRequestAndRespondAsync(Int32 port, String path, Func`2 responseProducer, CancellationToken cancellationToken)

【问题讨论】:

  • 我遇到了同样的问题
  • @DanSoltesz 运气好吗?我现在把它放在板凳上。

标签: sql azure asp.net-core entity-framework-core msal


【解决方案1】:

我最终得到了工作。在您部署的连接字符串的 appsettings 中将其设置为

Authentication=Active Directory Managed Identity;User Id='your azure object/principal id'

确保用户 ID 是天蓝色对象/主体 ID,而不是天蓝色客户端 ID

我创建了一个帮助程序,因此我不必直接在连接字符串中设置 userId,但在部署到 azure 时它会作为环境变量被拾取。您可以从配置中获取连接字符串,在我的情况下,我有一个租户服务来获取连接字符串,因为我的站点是多租户

public static SqlConnection Create(ITenantService tenantService, IConfiguration configuration)
{
    var tenantConnectionString = tenantService.GetConnectionString();
    var connectionStringBuilder = new SqlConnectionStringBuilder(tenantConnectionString);
    if (string.IsNullOrEmpty(connectionStringBuilder.UserID))
    {
        var clientId = configuration.GetValue<string>("AZURE_OBJECT_ID");
        if (clientId != null) connectionStringBuilder.UserID = clientId;
    }

    return new SqlConnection(connectionStringBuilder.ConnectionString);
}

然后在你的启动中使用

 optionsBuilder.UseSqlServer(MyUtility.Create(TenantService, Configuration));

【讨论】:

    猜你喜欢
    • 2018-05-29
    • 2020-11-10
    • 1970-01-01
    • 2019-11-15
    • 2017-09-05
    • 2018-01-22
    • 2016-02-14
    • 2022-10-04
    • 2017-01-16
    相关资源
    最近更新 更多