Blazor Server 7.0应用程序,具有图形Azure AD身份验证和OnRedirectToIdentityProviderForSignOut

nnvyjq4y  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(111)

我是Blazor的新手,但我是asp.net的长期开发人员。我正在尝试在Blazor中开发一个需要Azure AD身份验证的新应用程序。我已经设法将几乎所有内容整合在一起并使解决方案正常工作。我已经在Microsoft Entry ID中注册了应用程序,配置了appsettings.json文件,并将我设法找到的“示例”代码添加到Program.cs文件中。
一切都正常,除了注销时的“重定向”。我可以让它正常工作,但更改会导致“登录”和“注销”操作发生变化,这是我试图解决的问题。
下面是我想要的行为(除了显示空白页面的最后一步)
如果没有重定向更改,应用程序将打开并显示一个带有登录链接的默认页面,单击该链接将执行以下操作:
1.出现Microsoft“选择帐户”弹出窗口
1.用户单击帐户(或“使用另一个帐户”)选项
1.用户登录后,将显示默认主页,其中包含注销选项。
1.用户点击“注销”链接。
1.出现Microsoft“选择帐户”弹出窗口
1.用户单击相应的帐户
1.弹出窗口更改为“等待我们将您注销”
1.弹出窗口更改为“成功注销,您应该关闭所有浏览器”
1.弹出窗口消失,用户被重定向到一个空白屏幕。
当我添加以下代码时:

builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
            {
                options.Events.OnRedirectToIdentityProviderForSignOut = async context =>
                {
                    context.Options.SignedOutRedirectUri = "/";
                    context.HttpContext.Response.Redirect(context.Options.SignedOutRedirectUri);
                    context.HandleResponse();

                };
            });

字符串
然后运行应用程序,我得到了一个非常不同的登录过程:
1.用户点击登录按钮
1.用户的当前域帐户(类似于为Windows身份验证设置IIS时的asp.net)已登录。
1.用户点击注销按钮
1.用户将注销并重定向到应用程序默认页。
我喜欢简单的注销过程,但是,我需要原来的登录过程(提示哪个帐户登录)继续工作。
我是否在事件处理程序设置中遗漏了什么?如果我删除这部分代码,应用程序将返回到先前的登录/注销过程。
如果有帮助,这里是整个“公共类程序”:

public class Program
    {
        //Local private variable to provide read access to the Application Configuration file "appsettings.json"
        private static readonly IConfiguration appConfig_ = new ConfigurationBuilder().AddJsonFile("appsettings.json").AddEnvironmentVariables().Build();

        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            //BEGIN: JLK - 231107
            // Added the following items to handle configuration to use Microsoft identity for Authentication and Authorization
            var initialScopes = appConfig_.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');

            // This is required to be instantiated before the OpenIdConnectOptions starts getting configured.
            // By default, the claims mapping will map claim names in the old format to accommodate older SAML applications.
            // 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role' instead of 'roles'
            // This flag ensures that the ClaimsIdentity claims collection will be built from the claims in the token.
            JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

            // Add authentication with Microsoft identity platform.
            // EnableTokenAcquisitionToCallDownstreamApi - adds support for the web app to acquire tokens to call the API.
            // AddMicrosoftGraph - adds support to call Microsoft Graph
            builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(appConfig_.GetSection("AzureAd"))
                    .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
                        .AddMicrosoftGraph(appConfig_.GetSection("DownstreamApi"))
                        .AddInMemoryTokenCaches();

            builder.Services.AddControllersWithViews()
                .AddMicrosoftIdentityUI();

            builder.Services.AddAuthorization(options =>
            {
                // By default, all incoming requests will be authorized according to the default policy
                //options.FallbackPolicy = options.DefaultPolicy; --This was the original "policy" (I don't fully understand this yet) but it caused the "login" to occur before app displayed

                //This policy seems to allow the application to display without authentication, allowing the user to press the "login" button.
                var policy_ = new AuthorizationPolicyBuilder()
                                      .RequireAuthenticatedUser()
                                      .Build();
                options.AddPolicy("Required", policy_);
            });

            // Add the incremental consent and conditional access handler for Blazor server side pages.
            builder.Services.AddServerSideBlazor()
                .AddMicrosoftIdentityConsentHandler();

            //Added the following section to handle redirection user to app home page after successful logout
            //NOTE: After adding this code I notice that I no loger get the login prompt to select an account, nor do I get the logout prompt to select which account to logout
            //      but it does seem to work and user is redirected to the home page..
            builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
            {
                options.Events.OnRedirectToIdentityProviderForSignOut = async context =>
                {
                    context.Options.SignedOutRedirectUri = "/";
                    context.HttpContext.Response.Redirect(context.Options.SignedOutRedirectUri);
                    context.HandleResponse();

                };
            });
            //END: JLK - 231107

            //-------------Original STuff-------------------------
            // Add services to the container.
            builder.Services.AddRazorPages();
            //builder.Services.AddServerSideBlazor();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseStaticFiles();

            app.UseRouting();

            //BEGIN: JLK - 231107
            //added to to handle authorization and authentication
            // NOTE: I have not found any difference in app with both UseAuthentication() and UseAuthorization() commented out, so not really sure what these do.
            app.UseAuthentication();
            app.UseAuthorization();
            app.MapControllers();
            //END: JLK - 231107

            app.MapBlazorHub();
            app.MapFallbackToPage("/_Host");

            app.Run();
        }
    }


我尝试添加Redirect事件代码,并期望原始的登录/注销过程,注销后只有最后一页是应用程序主页,而不是默认的空白页。我见过其他例子,其中“最后一页”(对我来说是空白的)是一个简单的页面(不在应用程序布局表单中),上面写着“xxxx用户已成功注销”。

w3nuxt5m

w3nuxt5m1#

  • 我能够通过进行以下更改成功运行应用程序。我已经从您的代码中删除了以下行,*
//context.Options.SignedOutRedirectUri = "/";
//context.HttpContext.Response.Redirect(context.Options.SignedOutRedirectUri);
//context.HandleResponse();

字符串

产品代码:

using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web.UI;
using Microsoft.Identity.Web;
using System.IdentityModel.Tokens.Jwt;

public class Program
{
    private static readonly IConfiguration appConfig_ = new ConfigurationBuilder().AddJsonFile("appsettings.json").AddEnvironmentVariables().Build();
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var initialScopes = appConfig_.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');
        JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

        builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(appConfig_.GetSection("AzureAd"))
                .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
                    .AddMicrosoftGraph(appConfig_.GetSection("DownstreamApi"))
                    .AddInMemoryTokenCaches();

        builder.Services.AddControllersWithViews()
            .AddMicrosoftIdentityUI();

        builder.Services.AddAuthorization(options =>
        {
            var policy_ = new AuthorizationPolicyBuilder()
                                  .RequireAuthenticatedUser()
                                  .Build();
            options.AddPolicy("Required", policy_);
        });

        builder.Services.AddServerSideBlazor()
            .AddMicrosoftIdentityConsentHandler();
        builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
        {
            options.Events.OnRedirectToIdentityProviderForSignOut = async context =>
            {
                //context.Options.SignedOutRedirectUri = "/";
                //context.HttpContext.Response.Redirect(context.Options.SignedOutRedirectUri);
                //context.HandleResponse();

            };
        });

        builder.Services.AddRazorPages();
        var app = builder.Build();
        if (!app.Environment.IsDevelopment())
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();
        app.MapControllers();

        app.MapBlazorHub();
        app.MapFallbackToPage("/_Host");

        app.Run();
    }
}

  • 输出:*

成功运行如下,


的数据

浏览器输出:

我点击了下面的登录按钮,



Microsoft**“选择帐户”**弹出窗口出现,我点击我的帐户登录如下,



我现在登录了,默认首页显示有一个退出选项。我点击了下面的退出按钮,



Microsoft**“选择帐户”**弹出窗口出现,我将我的帐户设置为注销,如下所示,

我可以看到弹出窗口为您已注销帐户。最好关闭所有浏览器窗口,如下所示,

我已经成功注销,如下所示。

相关问题