我正在Dotnet核心Web应用程序中使用Azure AD登录,应该会触发OnAuthorizationCodeReceived事件,但未触发。
您能对此提供一些启示吗?
public void Configure(string name, OpenIdConnectOptions options)
{
JsonFileConfigurationService config = new JsonFileConfigurationService();
options.ClientId = config.AzureAdClientId;
options.Authority = $"{config.AzureAdInstance}{config.AzureAdTenantId}";
options.UseTokenLifetime = true;
options.CallbackPath = config.AzureAdCallbackPath;
options.RequireHttpsMetadata = false;
var allScopes = $"{_azureOptions.Scopes} {_azureOptions.GraphScopes}".Split(new[] { ' ' });
foreach (var scope in allScopes) { options.Scope.Add(scope); }
options.TokenValidationParameters = new TokenValidationParameters
{
// Instead of using the default validation (validating against a single issuer value, as we do in line of business apps),
// we inject our own multitenant validation logic
ValidateIssuer = false,
// If the app is meant to be accessed by entire organizations, add your issuer validation logic here.
//IssuerValidator = (issuer, securityToken, validationParameters) => {
// if (myIssuerValidationLogic(issuer)) return issuer;
//}
};
options.Events = new OpenIdConnectEvents
{
OnTicketReceived = context =>
{
// If your authentication logic is based on users then add your logic here
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
context.Response.Redirect("/Home/Error");
context.HandleResponse(); // Suppress the exception
return Task.CompletedTask;
},
OnAuthorizationCodeReceived = async (context) =>
{
var code = context.ProtocolMessage.Code;
var identifier = context.Principal.FindFirst(config.AzureAdObjectIdentifierType).Value;
var memoryCache = context.HttpContext.RequestServices.GetRequiredService<IMemoryCache>();
var graphScopes = _azureOptions.GraphScopes.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var cca = new ConfidentialClientApplication(
_azureOptions.ClientId,
_azureOptions.BaseUrl + _azureOptions.CallbackPath,
new ClientCredential(_azureOptions.ClientSecret),
new SessionTokenCache(identifier, memoryCache).GetCacheInstance(),
null);
var result = await cca.AcquireTokenByAuthorizationCodeAsync(code, graphScopes);
// Check whether the login is from the MSA tenant.
// The sample uses this attribute to disable UI buttons for unsupported operations when the user is logged in with an MSA account.
var currentTenantId = context.Principal.FindFirst(config.AzureAdTenantId).Value;
if (currentTenantId == "9188040d-6c67-4c5b-b112-36a304b66dad")
{
// MSA (Microsoft Account) is used to log in
}
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
},
// If your application needs to do authenticate single users, add your user validation below.
//OnTokenValidated = context =>
//{
// return myUserValidationLogic(context.Ticket.Principal);
//}
};
}
最佳答案
我遇到过类似的问题,似乎没有调用事件。不幸的是,没有看到更多的代码。我假设您提供的方法在实现IConfigureNamedOptions<OpenIdConnectOptions>
的类中。
我猜您还通过断点或日志记录证明了该方法实际上已被调用。
要尝试的另一件事是停止将新的OpenIdConnectEvents
实例分配给options.Events
(即options.Events = new OpenIdConnectEvents
)。 OpenIdConnectOptions
的构造函数将一个值分配给Events
属性,因此,通过将新实例重新分配给该属性,可以丢弃其他配置代码可能已添加的所有事件 Hook 。我在网上找到的许多示例代码确实会像您一样分配一个新实例,但似乎可能会给我带来问题。或者,将您的事件代码添加到现有实例中,例如
options.Events.OnAuthorizationCodeReceived = async (context) =>
{
var code = context.ProtocolMessage.Code;
var identifier = context.Principal.FindFirst(config.AzureAdObjectIdentifierType).Value;
var memoryCache = context.HttpContext.RequestServices.GetRequiredService<IMemoryCache>();
var graphScopes = _azureOptions.GraphScopes.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var cca = new ConfidentialClientApplication(
_azureOptions.ClientId,
_azureOptions.BaseUrl + _azureOptions.CallbackPath,
new ClientCredential(_azureOptions.ClientSecret),
new SessionTokenCache(identifier, memoryCache).GetCacheInstance(),
null);
var result = await cca.AcquireTokenByAuthorizationCodeAsync(code, graphScopes);
// Check whether the login is from the MSA tenant.
// The sample uses this attribute to disable UI buttons for unsupported operations when the user is logged in with an MSA account.
var currentTenantId = context.Principal.FindFirst(config.AzureAdTenantId).Value;
if (currentTenantId == "9188040d-6c67-4c5b-b112-36a304b66dad")
{
// MSA (Microsoft Account) is used to log in
}
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
当然,这仍然意味着您可能会覆盖其他一些处理程序(即
options.Events.OnAuthorizationCodeReceived
可能已经有一个处理程序)。因此,您可以先捕获它,然后等待结果,例如var existingHandler = options.Events.OnAuthorizationCodeReceived;
options.Events.OnAuthorizationCodeReceived = async (context) =>
{
await existingHandler(context);
// Your code here...
}
最后,如果您在
AzureAdAuthenticationBuilderExtensions.AddAzureAd
方法中使用Startup.ConfigureServices
方法,则按照上述讨论,检查ConfigureAzureOptions.Configure
方法没有分配新的OpenIdConnectEvents
。关于c# - OpenIdConnectEvents OnAuthorizationCodeReceived不触发,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50209838/