.net 当TokenAcquisition失败时,如何处理MicrosoftIdentityWebChallengeUserException?
我正在构建一个Web应用程序,当我重新启动应用程序并尝试使用.net 当TokenAcquisition失败时,如何处理MicrosoftIdentityWebChallengeUserException?,.net,azure-active-directory,azure-web-app-service,msal,.net-5,.net,Azure Active Directory,Azure Web App Service,Msal,.net 5,我正在构建一个Web应用程序,当我重新启动应用程序并尝试使用ITokenAcquisition.GetTokenFourserAsync “出现一个或多个错误。(IDW10502:由于用户的质询而引发MsalUiRequiredException。请参阅)。” 我正在使用Microsoft.Identity.Web根据Azure广告对用户进行身份验证 当我检查令牌缓存时,它在重新启动应用程序后为空。如果用户已经从以前的会话登录,或者因为他们正在使用加入域的设备,那么他们似乎会绕过缓存 如何强制重
ITokenAcquisition.GetTokenFourserAsync
“出现一个或多个错误。(IDW10502:由于用户的质询而引发MsalUiRequiredException。请参阅)。”
我正在使用Microsoft.Identity.Web根据Azure广告对用户进行身份验证
当我检查令牌缓存时,它在重新启动应用程序后为空。如果用户已经从以前的会话登录,或者因为他们正在使用加入域的设备,那么他们似乎会绕过缓存
如何强制重新验证或向缓存中添加令牌
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
// Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
options.HandleSameSiteCookieCompatibility();
});
// Sign-in users with the Microsoft identity platform
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi(new[] { "https://database.windows.net//.default" })
.AddInMemoryTokenCaches();
services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy
options.FallbackPolicy = options.DefaultPolicy;
});
services.AddDbContext<MyDatabaseContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyAzureConnection")));
services.AddRazorPages()
.AddRazorRuntimeCompilation()
.AddMvcOptions(o => o.Filters.Add(new AuthorizeFilter()))
.AddMicrosoftIdentityUI();
}
public void配置服务(IServiceCollection服务)
{
配置(选项=>
{
//此lambda确定给定请求是否需要非必要cookie的用户同意。
options.checkApprovered=context=>true;
options.MinimumSameSitePolicy=SameSiteMode.Unspecified;
//根据标准处理SameSite cookiehttps://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
options.HandleSameSiteCookieCompatibility();
});
//使用Microsoft identity platform登录用户
services.AddMicrosoftIdentityWebAppAuthentication(配置)
.EnableTokenAcquisitionToCallDownstreamMapi(新[]{”https://database.windows.net//.default" })
.AddInMemoryTokenCaches();
services.AddAuthorization(选项=>
{
//默认情况下,将根据默认策略授权所有传入请求
options.FallbackPolicy=options.DefaultPolicy;
});
services.AddDbContext(选项=>
options.UseSqlServer(Configuration.GetConnectionString(“MyAzureConnection”));
services.AddRazorPages()
.AddRazorRuntimeCompilation()文件
.addmvcopions(o=>o.Filters.Add(new AuthorizeFilter()))
.AddMicrosoftIdentityUI();
}
我请求令牌的DbContext
public MyDatabaseContext (ITokenAcquisition tokenAcquisition,
DbContextOptions<MyDatabaseContext> options)
: base(options)
{
_tokenAcquisition = tokenAcquisition;
var token = _tokenAcquisition.GetAccessTokenForUserAsync(new[] {"https://database.windows.net//.default"});
var connection = (SqlConnection)Database.GetDbConnection();
connection.AccessToken = token.GetAwaiter().GetResult();
}
公共MyDatabaseContext(ITokenAcquisition tokenAcquisition,
DbContextOptions(选项)
:基本(选项)
{
_tokenAcquisition=tokenAcquisition;
var token=\u tokenAcquisition.GetAccessTokenForUserAsync(新[]{”https://database.windows.net//.default"});
var connection=(SqlConnection)Database.GetDbConnection();
connection.AccessToken=token.GetAwaiter().GetResult();
}
我的所有页面模型都用[AuthorizeForScopes(scopekeyssection=“AzureSQL:BaseUrl”)]
装饰,这意味着:
AADSTS65001:用户或管理员尚未同意使用
ID为“{appId}”且名为“{appName}”的应用程序。发送一个交互式
此用户和资源的授权请求
缓解措施:
首先获得用户同意。如果您没有使用.NET Core(它没有任何Web UI),请调用(仅一次)
AcquireTokeninteractive
。如果您正在使用.NET core或不想执行AcquireTokenInteractive
,用户可以导航到URL以给予同意:https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response\u type=code&scope=user.read
。调用AcquireTokenInteractive
:app.AcquireTokenInteractive(作用域).WithAccount(帐户).WithClaims(例如Claims.ExecuteAsync()代码>在我的例子中,我在使用.Net Core 3.1 Web应用程序时遇到了MicrosoftIdentityWebChallengeUserException
。控制器操作中的我的代码:
string[] scopes = new string[] { "user.read", "https://storage.azure.com/user_impersonation" };
try
{
ViewData["token"] = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes);
return View();
}
catch (MicrosoftIdentityWebChallengeUserException ex)
{
throw ex.MsalUiRequiredException;
}
请注意catch块MicrosoftIdentityWebChallengeUserException
具有访问MSAlluiRequiredException
的属性。我不得不抛出该异常以强制Identity Web UI再次显示同意UI。我是从你那里得到这个消息的。请看其中的MVC控制器部分。上面说,
AuthorizeForScopesAttribute继承自ExceptionFilterAttribute,这意味着它处理MSAL.NET MsalUiRequiredException以处理条件访问和增量同意。这还意味着,如果捕获MSAL异常,则应重新抛出捕获的MSAL异常,以便属性能够处理它
第二句话让我很开心!应该突出显示以节省我们的时间
另外,这是我在准备AZ204时的示例应用程序。起初我没有包括存储模拟范围,但后来添加了它。然后应用程序开始抛出上述异常,我必须找到一种方法再次显示同意用户界面。谢谢,这为我指明了正确的方向。我大量借用了Microsoft.Identity.Web中的一个服务,其中包含ChallengeUser方法(以下链接)。