C# 使用Authentication.AzureAD.UI库时实现OpenIdConnectOptions事件
我一直在使用从示例创建的库,该库允许我使用Azure Active Directory验证.NET核心web应用程序,并利用各种C# 使用Authentication.AzureAD.UI库时实现OpenIdConnectOptions事件,c#,asp.net-core,azure-active-directory,openid-connect,C#,Asp.net Core,Azure Active Directory,Openid Connect,我一直在使用从示例创建的库,该库允许我使用Azure Active Directory验证.NET核心web应用程序,并利用各种OpenIdConnectOptions事件(例如OnTokenValidated)将某些声明添加到主体中,并将该数据添加到类似身份的数据库中,以便API可以基于其令牌对调用方进行基于策略的确定 但是我宁愿使用Microsoft.AspNetCore.Authentication.AzureAD.UINuGet软件包,也不愿使用我的定制版本,我只是不知道如何进入并访问O
OpenIdConnectOptions
事件(例如OnTokenValidated
)将某些声明添加到主体中,并将该数据添加到类似身份的数据库中,以便API可以基于其令牌对调用方进行基于策略的确定
但是我宁愿使用Microsoft.AspNetCore.Authentication.AzureAD.UI
NuGet软件包,也不愿使用我的定制版本,我只是不知道如何进入并访问OpenIdConnectOptions
上的事件
我不知道这是否是可以做到的,或者我只是对依赖注入没有足够的把握来弄清楚如何做到这一点
我是否应该考虑在过程的不同部分增加索赔等?
public static AuthenticationBuilder AddAzureAD(
this AuthenticationBuilder builder,
string scheme,
string openIdConnectScheme,
string cookieScheme,
string displayName,
Action<AzureADOptions> configureOptions) {
AddAdditionalMvcApplicationParts(builder.Services);
builder.AddPolicyScheme(scheme, displayName, o => {
o.ForwardDefault = cookieScheme;
o.ForwardChallenge = openIdConnectScheme;
});
builder.Services.Configure(
TryAddOpenIDCookieSchemeMappings(scheme, openIdConnectScheme, cookieScheme));
builder.Services.TryAddSingleton<IConfigureOptions<AzureADOptions>, AzureADOptionsConfiguration>();
// They put in their custom OpenIdConnect configuration, but I can't see how to get at the events.
builder.Services.TryAddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectOptionsConfiguration>();
builder.Services.TryAddSingleton<IConfigureOptions<CookieAuthenticationOptions>, CookieOptionsConfiguration>();
builder.Services.Configure(scheme, configureOptions);
builder.AddOpenIdConnect(openIdConnectScheme, null, o => { });
builder.AddCookie(cookieScheme, null, o => { });
return builder;
}
publicstaticauthenticationbuilder AddAzureAD(
此AuthenticationBuilder,
字符串方案,
字符串openIdConnectScheme,
字符串cookieScheme,
字符串显示名,
操作(配置选项){
添加额外的MVCAP应用部件(建筑商服务);
builder.AddPolicyScheme(scheme,displayName,o=>{
o、 ForwardDefault=cookieScheme;
o、 ForwardChallenge=openIdConnectScheme;
});
builder.Services.Configure(
tryaddopendcookieschemesappings(scheme、openIdConnectScheme、cookieScheme));
builder.Services.TryAddSingleton();
//他们加入了自定义的OpenIdConnect配置,但我看不出如何参与这些活动。
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.Configure(方案、配置选项);
AddOpenIdConnect(openIdConnectScheme,null,o=>{});
AddCookie(cookieScheme,null,o=>{});
返回生成器;
}
您可以在AzureADOptionsConfiguration>类()下定义的配置函数中添加OnTokenValidated事件。如下
我可能在这里参加聚会有点晚,但我遇到了同样的问题,发现AzureAD认证中间件的文档非常稀少。在这里为其他与同一问题斗争的人添加解决方案 正如您在问题的代码段底部所看到的,AzureAD提供程序实际上依赖于罩下的
OpenIdConnect
和Cookie
身份验证提供程序,并且本身不实现任何身份验证逻辑
为此,添加了两个额外的身份验证方案,分别使用定义为AzureADDefaults.OpenIdScheme
和AzureADDefaults.CookieScheme
的名称
(尽管在使用AddAzureAD(此Microsoft.AspNetCore.Authentication.AuthenticationBuilder生成器、字符串方案、字符串openIdConnectScheme、字符串cookieScheme、字符串显示名称、操作配置选项)时,也可以自定义名称)
重载)
这反过来允许通过使用上面的方案名称配置有效的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
{
// ...
};
});
services.AddAuthentication(AzureAddFaults.AuthenticationScheme)
.AddAzureAD(options=>Configuration.Bind(“AzureAd”,options));
配置(AzureADDefaults.OpenIdScheme,选项=>
{
options.Events=新的OpenIdConnectEvents
{
OnRedirectToIdentityProvider=异步ctxt=>
{
//在重定向到身份提供程序进行身份验证之前调用。这可用于设置ProtocolMessage.State
//协议消息还可以用于添加或自定义
//发送到标识提供程序的参数。
等待任务;
},
OnMessageReceived=异步ctxt=>
{
//在第一次收到协议消息时调用。
等待任务;
},
OnTicketReceived=async ctxt=>
{
//在收到远程票证后调用。
//可用于在将主体传递给Cookie方案进行登录之前修改主体。
//此示例从主体中删除所有“组”声明(假设已配置AAD应用程序)
//使用“groupMembershipClaims”:“SecurityGroup”)。可以在此处检查组成员身份并将其转换为
//角色,将保留在cookie中。
if(ctxt.Principal.Identity是索赔实体标识)
{
ctxt.Principal.FindAll(x=>x.Type==“组”)
托利斯先生()
.ForEach(identity.RemoveClaim);
}
等待任务;
},
};
});
配置(AzureADDefaults.CookieScheme,选项=>
{
options.Events=新建CookieAuthenticationEvents
{
// ...
};
});
我认为基于official,您还可以创建一个单独的处理程序类,如下所示:
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);
}
}
这样,您就可以在
选项.Events的处理程序中运行一些更复杂的逻辑,因为您可以插入任何您想要的服务。那么,使用Microsoft.AspNetCore.Authentication.AzureAD.UI
NuGet包在startup.cs中会是什么样子呢<代码>服务.AddAuthentication(azureAddFaults.AuthenticationScheme).AddAzureAD(选项=>Con
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind(nameof(AzureAdConfig), options));
// registration of other services
services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, AzureAdOpendIdHandler>();