我一直在使用从示例创建的库,该库使我可以通过Azure Active Directory验证.NET核心Web应用并利用各种@SafeVarargs
public static <T> ObservableList<T> concat(ObservableList<T>... sources) {
return new ListBinding<T>() {
{
bind(sources);
}
@Override
protected ObservableList<T> computeValue() {
return FXCollections.concat(sources);
}
};
}
事件(例如OpenIdConnectOptions
)进行添加对委托人的某些要求,以及将数据添加到类似身份的数据库中,以便API可以基于调用者的令牌对调用者进行基于策略的确定。
但是我宁愿使用OnTokenValidated
NuGet软件包,也不愿使用我的自定义版本,我只是不确定如何进入Microsoft.AspNetCore.Authentication.AzureAD.UI
并访问事件。
我不知道这是不是可以做的事,或者我只是没有足够的依赖注入处理方法来弄清楚该怎么做。
还是我应该考虑在流程的其他部分添加索赔等?
OpenIdConnectOptions
答案 0 :(得分:4)
我可能在这里参加聚会有点晚了,但是我遇到了同样的问题,发现AzureAD身份验证中间件的文档非常稀疏。在这里为其他遇到相同问题的人添加解决方案。
正如您在问题的代码片段底部所看到的那样,AzureAD提供程序实际上依赖于幕后的OpenIdConnect
和Cookie
身份验证提供程序,并且本身未实现任何身份验证逻辑。
为此,添加了两个附加的身份验证方案,分别使用定义为AzureADDefaults.OpenIdScheme
和AzureADDefaults.CookieScheme
的名称。
(尽管使用AddAzureAD(this Microsoft.AspNetCore.Authentication.AuthenticationBuilder builder, string scheme, string openIdConnectScheme, string cookieScheme, string displayName, Action<Microsoft.AspNetCore.Authentication.AzureAD.UI.AzureADOptions> configureOptions)
重载也可以自定义名称)。
这又允许通过使用上方的方案名称来配置有效的OpenIdConnectOptions
和CookieAuthenticationOptions
,包括对OpenIdConnectEvents
的访问。
请参见以下完整示例:
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async ctxt =>
{
// Invoked before redirecting to the identity provider to authenticate. This can be used to set ProtocolMessage.State
// that will be persisted through the authentication process. The ProtocolMessage can also be used to add or customize
// parameters sent to the identity provider.
await Task.Yield();
},
OnMessageReceived = async ctxt =>
{
// Invoked when a protocol message is first received.
await Task.Yield();
},
OnTicketReceived = async ctxt =>
{
// Invoked after the remote ticket has been received.
// Can be used to modify the Principal before it is passed to the Cookie scheme for sign-in.
// This example removes all 'groups' claims from the Principal (assuming the AAD app has been configured
// with "groupMembershipClaims": "SecurityGroup"). Group memberships can be checked here and turned into
// roles, to be persisted in the cookie.
if (ctxt.Principal.Identity is ClaimsIdentity identity)
{
ctxt.Principal.FindAll(x => x.Type == "groups")
.ToList()
.ForEach(identity.RemoveClaim);
}
await Task.Yield();
},
};
});
services.Configure<CookieAuthenticationOptions>(AzureADDefaults.CookieScheme, options =>
{
options.Events = new CookieAuthenticationEvents
{
// ...
};
});
答案 1 :(得分:4)
我认为,根据官方Microsoft code base,您还可以创建一个像这样的单独的处理程序类:
memcpy(spubB.BytePtr(),(B Static public key's byte array),spubB.SizeInBytes()); //Sets the public static key.
memcpy(epubB.BytePtr(),(B Public ephemeral key's byte array),epubB.SizeInBytes()); //Sets the ephemeral key.
然后,您只需在public class AzureAdOpendIdHandler : IConfigureNamedOptions<OpenIdConnectOptions>
{
private readonly AzureAdConfig _azureOptions;
readonly IMediator _mediator;
public AzureAdConfig GetAzureAdConfig() => _azureOptions;
public AzureAdOpendIdHandler(IOptions<SiteConfig> siteConfig, IMediator mediator)
{
_azureOptions = siteConfig.Value.AzureAdConfig;
_mediator = mediator;
}
public void Configure(string name, OpenIdConnectOptions options)
{
options.ClientId = _azureOptions.ClientId;
options.UseTokenLifetime = true;
options.CallbackPath = _azureOptions.CallbackPath;
options.RequireHttpsMetadata = false;
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.TokenValidationParameters = new TokenValidationParameters
{
// Ensure that User.Identity.Name is set correctly after login
NameClaimType = "name",
ValidateIssuer = false,
};
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = context =>
{
var idToken = context.SecurityToken;
string userIdentifier = idToken.Subject;
string userEmail =
idToken.Claims.SingleOrDefault(c => c.Type == JwtRegisteredClaimNames.Email)?.Value
?? idToken.Claims.SingleOrDefault(c => c.Type == "preferred_username")?.Value;
string firstName = idToken.Claims.SingleOrDefault(c => c.Type == JwtRegisteredClaimNames.GivenName)?.Value;
string lastName = idToken.Claims.SingleOrDefault(c => c.Type == JwtRegisteredClaimNames.FamilyName)?.Value;
string name = idToken.Claims.SingleOrDefault(c => c.Type == "name")?.Value;
// manage roles, modify token and claims etc.
return Task.CompletedTask;
},
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;
},
};
}
public void Configure(OpenIdConnectOptions options)
{
Configure(Options.DefaultName, options);
}
}
方法末尾的某个地方注册Startup.cs
像这样:
ConfigureServices(IServiceCollection services)
这样,您就可以在services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind(nameof(AzureAdConfig), options));
// registration of other services
services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, AzureAdOpendIdHandler>();
的处理程序中运行一些更复杂的逻辑,因为您可以注入所需的任何服务。
答案 2 :(得分:-1)