【问题标题】:Change Azure AD B2C SignOut URL (Change AzureADB2C/Account/SignedOut to custom URL)更改 Azure AD B2C 注销 URL(将 AzureADB2C/Account/SignedOut 更改为自定义 URL)
【发布时间】:2019-11-17 12:08:41
【问题描述】:

我目前正在构建一个使用 Azure B2C OIDC 进行登录/身份验证的 C# Net Core 2.2 应用程序。我已经自定义了登录页面,并且知道如何使用自定义页面布局使用托管在我的网站上的 CSS 和代码自定义编辑/忘记密码屏幕。

我遇到的问题是在注销时,我被重定向到 /AzureADB2C/Account/SignOut。我想像使用登录页面一样修改 CSS,或者更改该 URL 以转到我网站上托管的自定义控制器操作。

有谁知道管理它的方法/流程是什么?似乎很奇怪,他们会为“除”注销过程之外的所有内容提供自定义布局。

作为一种解决方法,我发现我可以添加一个“重写选项”来处理 SignOut URL 并将其重写到我网站上的控制器。 但是,我不确定这是否是实现此目的的最佳方式 任务,它在一个非常不起眼的 MSDN 页面上,但它确实有效。见下文:

// Inside Startup.cs
// Workaround for SignedOut URL error in MSFT code 
RewriteOptions rewrite = new RewriteOptions().AddRedirect("AzureADB2C/Account/SignedOut","Account/SignedOut"); 
app.UseRewriter(rewrite);

【问题讨论】:

    标签: c# azure azure-ad-b2c


    【解决方案1】:

    目前我们无法使用自定义页面布局直接自定义退出 UI。

    使用RewriteOptions() 方法对您来说是一种可选方法。或者,您可以构建自己的 AccountController,而不是使用 ASP.NET CORE 附带的默认控制器。它们的原理是一样的。

    【讨论】:

      【解决方案2】:

      我认为您正在使用用户流(策略)来自定义您的登录/个人资料编辑/密码重置页面。您可能会注意到没有 Signout 用户流,因此您无法在此处执行任何操作。

      但是 MS 为您提供了另一种方式来拥有自己的注销后页面。当您从 Web 应用程序注销时,您应该重定向到 B2C 的注销端点,如 here 所述。 (注意:这就是你应该做的,即使你不想要自定义注销页面)

      当您想要让用户退出应用程序时,仅清除应用程序的 cookie 或以其他方式结束与用户的会话是不够的。将用户重定向到 Azure AD B2C 以注销。如果您不这样做,用户可能无需再次输入其凭据即可重新对您的应用程序进行身份验证。

      注销端点可以在查询字符串中接收可选的 post_logout_redirect_uri 参数,您可以在其中指定另一个 URL,您的用户最终将被 B2C 重定向到该 URL。这可以是任何资源的地址,例如您的主页或您自己的页面向用户显示“您已成功退出我们的服务”消息。

      post_logout_redirect_uri - 用户成功退出后应重定向到的 URL。 如果不包括在内,Azure AD B2C 会向用户显示一条通用消息。

      【讨论】:

        【解决方案3】:

        如果查看 Microsoft.AspNetCore.Authentication.AzureADB2C.UI nuget 包中 AccountController 的 source code,可以看到 callbackUrl 被硬编码为 (/AzureADB2C)/Account/SignedOut。

        但没有要求使用该控制器。只需在您自己的控制器上调用您自己的 SignOut 操作。复制粘贴 AzureADB2C SignOut 操作中的代码并将 callbackUrl 更改为您自己的。

        编辑 _LoginPartial.cshtml:删除 asp-area="AzureADB2C" 并将您自己的用于 asp-controller 和 asp-action。

        【讨论】:

        • 这意味着在使用 Blazor 时,我们应该仅为这个需求创建一个 AccountController。我会尝试使用 RewriteOption 方式。
        • @Sven ,不用控制器也可以,刚刚贴了我关于如何更改回调 URL 的笔记
        【解决方案4】:

        [@Marcel W 提供的答案和@Sven 提出的问题的其他信息]

        聚会有点晚了,但万一它可以帮助别人:

        • Blazor 服务器应用 .net core 3.1
        • 身份验证:Azure B2C

        原代码在下面repository

        不幸的是,在注销方法中,回调 url 是硬编码的。

                [HttpGet("{scheme?}")]
                public async Task<IActionResult> SignOut([FromRoute] string scheme)
                {
                    scheme = scheme ?? AzureADB2CDefaults.AuthenticationScheme;
                    var authenticated = await HttpContext.AuthenticateAsync(scheme);
                    if (!authenticated.Succeeded)
                    {
                        return Challenge(scheme);
                    }
        
                    var options = _options.Get(scheme);
        
                    var callbackUrl = Url.Page("/Account/SignedOut", pageHandler: null, values: null, protocol: Request.Scheme);
                    return SignOut(
                        new AuthenticationProperties { RedirectUri = callbackUrl },
                        options.AllSchemes);
                }
        

        所以想法是获取代码并在项目中创建相同的行为。

        1. 创建区域文件夹
        2. 在 Areas 文件夹中创建 AzureADB2C 文件夹
        3. 在 AzureADB2C 文件夹中创建 Pages 文件夹
        4. 在 Pages 文件夹中创建 Account 文件夹
        5. 在 Account 文件夹中创建 SignOut.cshtml 文件
        6. 复制/粘贴以下代码
        
        @page
        @using Microsoft.AspNetCore.Authentication
        @using Microsoft.AspNetCore.Authentication.AzureADB2C.UI
        @using Microsoft.Extensions.Options
        @inject IOptionsMonitor<AzureADB2COptions> Options
        @attribute [IgnoreAntiforgeryToken]
        @functions {
            public async Task<IActionResult> OnPost([FromRoute] string scheme)
            {
                scheme = scheme ?? AzureADB2CDefaults.AuthenticationScheme;
                var authenticated = await HttpContext.AuthenticateAsync(scheme);
                if (!authenticated.Succeeded)
                {
                    return Challenge(scheme);
                }
        
                var options = Options.Get(scheme);
        
                var callbackUrl = Url.Page("/", pageHandler: null, values: null, protocol: Request.Scheme);
                return SignOut(
                    new AuthenticationProperties { RedirectUri = callbackUrl },
                    options.AllSchemes);
            }
        }
        

        最后的修改将在 LoginDisplay.razor 文件中进行。我们需要创建一个表单来完成我们的“发布”以签署用户

        替换此文件中的以下行

            <a href="AzureADB2C/Account/SignOut">Log out</a>
        

            <form method="post" action="AzureADB2C/Account/SignOut">
                <button type="submit" class="nav-link btn btn-link">Log out</button>
            </form>
        

        下面是说明目录结构的屏幕截图

        【讨论】:

          【解决方案5】:

          根据https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/127 试试这个(对我有用):

          对于 MSA 帐户,如果出现以下情况,注销页面应重定向回您的应用:

          用户已使用/同意客户端应用

          注销 uri 是 https

          注销 uri 在门户中注册为回复 uri

          注销 uri 注册为 post logout url

          注销 uri 在 msal 中设置为 auth.postLogoutRedirectUri(并且您调用注销)。

          【讨论】:

            【解决方案6】:

            我基于上述答案的解决方案

            在你的控制器上

            Source Code复制粘贴SignOut功能

            您需要注入 IOptionsMonitor _azure(在我的情况下)

             [HttpGet("logout/{scheme?}")]
                public async Task<IActionResult> SignOut([FromRoute] string scheme)
                {
                    scheme = scheme ?? AzureADB2CDefaults.AuthenticationScheme;
                    var authenticated = await HttpContext.AuthenticateAsync(scheme);
                    if (!authenticated.Succeeded)
                    {
                        return Challenge(scheme);
                    }
            
                    var options = _azure.Get(scheme);
            
                    var callbackUrl = "/";
                    return SignOut(
                        new AuthenticationProperties { RedirectUri = callbackUrl },
                        options.AllSchemes);
                }
            

            之后,您只需要从您的视图或前端调​​用控制器

            【讨论】:

              【解决方案7】:

              查看library at github 后 - 已链接 其他答案 - 我最终得到以下结果:

              @if (ViewData["Title"].Equals("Signed out"))
              {
                  <div class="content">Abgemeldet!</div>
              }
              @string mainStyle = ViewData["Title"].Equals("Signed out") ? "display:none;" : string.Empty;
              <main style=@mainStyle>
                   @RenderBody()
              </main>
              

              我知道.. 有点- 紧紧地绑定到库中的字符串常量...但非常实用...

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-05-20
                • 1970-01-01
                • 1970-01-01
                • 2020-11-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多