使用Authentication.AzureAD.UI库时实现OpenIdConnectOptions事件

时间:2018-07-18 23:59:44

标签: c# asp.net-core azure-active-directory openid-connect

我一直在使用从示例创建的库,该库使我可以通过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

3 个答案:

答案 0 :(得分:4)

我可能在这里参加聚会有点晚了,但是我遇到了同样的问题,发现AzureAD身份验证中间件的文档非常稀疏。在这里为其他遇到相同问题的人添加解决方案。

正如您在问题的代码片段底部所看到的那样,AzureAD提供程序实际上依赖于幕后的OpenIdConnectCookie身份验证提供程序,并且本身未实现任何身份验证逻辑。

为此,添加了两个附加的身份验证方案,分别使用定义为AzureADDefaults.OpenIdSchemeAzureADDefaults.CookieScheme的名称。

(尽管使用AddAzureAD(this Microsoft.AspNetCore.Authentication.AuthenticationBuilder builder, string scheme, string openIdConnectScheme, string cookieScheme, string displayName, Action<Microsoft.AspNetCore.Authentication.AzureAD.UI.AzureADOptions> configureOptions)重载也可以自定义名称)。

这又允许通过使用上方的方案名称来配置有效的OpenIdConnectOptionsCookieAuthenticationOptions,包括对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)

您可以在您在类AzureADOptionsConfiguration>()下定义的Configure函数中添加OnTokenValidated事件。像下面 enter image description here