【问题标题】:Blazor (Server Side) and OktaBlazor(服务器端)和 Okta
【发布时间】:2020-04-14 23:44:18
【问题描述】:

我目前正在通过这篇文章将 okta 集成到 Blazor 服务器端应用程序中

https://developer.okta.com/blog/2019/10/16/csharp-blazor-authentication

我目前收到“抱歉,这个地址没有任何东西”。

我希望有人可以为我的问题提供建议。

或者有人知道将 okta 集成到 Blazor 服务器端应用程序中的示例吗?

请告诉我。

任何帮助将不胜感激。我完全在旋转我的轮子。

这是我的 okta 常规设置:

以下是我的解决方案中的代码(我多次查看该帖子以确保它是正确的。但我想我可能错过了一些东西。)

启动配置服务

       services.AddAuthorizationCore();
        services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.ClientId = Configuration["Okta:ClientId"];
                options.ClientSecret = Configuration["Okta:ClientSecret"];
                options.Authority = Configuration["Okta:Issuer"];
                options.CallbackPath = "/authorization-code/callback";
                options.ResponseType = "code";
                options.SaveTokens = true;
                options.UseTokenLifetime = false;
                options.GetClaimsFromUserInfoEndpoint = true;
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name"
                };
            });
    }

启动配置

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            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();

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

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
        });
    }

MainLayout.razor

<div class="top-row px-4">

    <AuthorizeView>
        <Authorized>
            <a href="Identity/Account/Manage">Hello, @context.User.Identity.Name!</a>
            <a href="Identity/Account/LogOut">Log out</a>
        </Authorized>
        <NotAuthorized>
            <a href="Identity/Account/Register">Register</a>
            <a href="Identity/Account/Login">Log in</a>
        </NotAuthorized>
    </AuthorizeView>

    <a href="https://docs.microsoft.com/en-us/aspnet/" target="_blank">About</a>
</div>

App.razor

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState> ```



【问题讨论】:

  • 你可以这样做吗:在 App 组件的顶部添加:@inject NavigationManager NavigationManager 在 元素中放置:@{ var returnUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri ); Console.WriteLine(returnUrl); } 请报告打印的值
  • 我得到的值是:"Identity/Account/Login"
  • 从这个选项开始。CallbackPath = "/authorization-code/callback";您已在此处发布了文件的图像。这个文件在世界上的什么地方?无论如何,看看你是否可以并且应该改变与那里相关的回调。它应该提供现有的 url。祝你好运,并报告
  • 好的,我会给它,这可能需要一点时间,但我会告诉你的。谢谢。

标签: blazor okta blazor-server-side


【解决方案1】:

当你点击“登录”锚元素时,路由器找不到“身份/帐户/登录”路径,结果显示

对不起,这个地址什么都没有。

.当然你没有被定向到 okta 网站,也没有进行身份验证,对吧?

我无法理解她为什么要这样设置 AuthorizeView 组件。不过,在我看来,她的整篇文章是由市委设计的,是用备用代码 sn-ps 组装而成的。但是,这超出了此答案的范围。

解决方案

  1. 创建一个名为 LoginDisplay (LoginDisplay.razor) 的组件,并将其放置在 Shared 文件夹中。该组件在MainLayout组件中使用

    <AuthorizeView> <Authorized> <a href="logout">Hello, @context.User.Identity.Name!</a> <form method="get" action="logout"> <button type="submit" class="nav-link btn btn-link">Log out</button> </form> </Authorized> <NotAuthorized> <a href="login?redirectUri=/">Log in</a> </NotAuthorized> </AuthorizeView>

    将 LoginDisplay 组件添加到 MainLayout 组件中,就在 About 上方 锚元素,像这样 <div class="top-row px-4"> <LoginDisplay /> <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> </div>

注意:为了将登录和注销请求重定向到 okta,我们必须创建两个 Razor 页面,如下所示: 1、创建一个Login Razor页面Login.cshtml(Login.cshtml.cs),并将它们放在Pages文件夹中,如下:

Login.cshtml.cs

 using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Authentication.OpenIdConnect;
 using Microsoft.AspNetCore.Authentication.Cookies;
 using Microsoft.IdentityModel.Tokens;

public class LoginModel : PageModel
{
    public async Task OnGet(string redirectUri)
    {
        await 
    HttpContext.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, 
    new AuthenticationProperties
    {
            RedirectUri = redirectUri
    });
  }
}

此代码启动您在 Startup 类中定义的 Open Id Connect 身份验证方案的质询。

  1. 创建一个 Logout Razor 页面 Logout.cshtml (Logout.cshtml.cs) 并将它们也放在 Pages 文件夹中:

    注销.cshtml.cs

using Microsoft.AspNetCore.Authentication; public class LogoutModel : PageModel { public async Task<IActionResult> OnGetAsync() { await HttpContext.SignOutAsync(); return Redirect("/"); } } 此代码将您注销,将您重定向到 Blazor 应用的主页。

将 App.razor 中的代码替换为以下代码:

<CascadingAuthenticationState>

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="@routeData" 
      DefaultLayout="@typeof(MainLayout)">
            <NotAuthorized>

                  @*<RedirectToLogin />*@
            </NotAuthorized>
            <Authorizing>
                Wait...
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
    <NotFound>

            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>

    </NotFound>

 </Router>
 </CascadingAuthenticationState>

运行你的应用,点击登录按钮进行身份验证

注意:我还没有完成我的答案...我还有更多要补充的,但我现在做不到。我会尽快做。如果您有任何问题,请随时提问。如果可以的话,我会回答他们的……;)

注意:这个示例非常适合我。

请不要忘记您的 appsettings.json 文件。应该是这样的:

{
  "Okta": {
    "Issuer": "https://dev-621531.okta.com/oauth2/default",
    "ClientId": "0o1a5bsivg6wFDw6Jr347",
    "ClientSecret": "ffolkG3sd2NgQ_E909etXRU3cXX3wBpgE0XxcmF5"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

不要尝试使用我的设置,因为我已经更改了它们... Startup 类中的代码是正确的,但您可能需要添加一些命名空间引用,可能是我添加的 nuget 包等。

注意:当你在试验你的应用时,你应该清除浏览数据,如果你想被重定向到 okta 的登录页面,否则你的浏览器可能会使用缓存的数据。

更新 请注意,在这里创建登录机制不会使您的应用程序比以前更安全。任何用户都无需登录即可访问您的网络资源。为了保护您网站的某些部分,您还必须实施授权,通常,经过身份验证的用户有权访问受保护的资源,除非实施其他措施,例如角色、策略等。以下是演示如何您可以保护您的 Fetchdata 页面免受未经授权的用户的攻击(同样,经过身份验证的用户被视为有权访问 Fetchdata 页面)。

  1. 在 Fetchdata 组件页面的顶部,为 Authorize 属性添加 @attribute 指令,如下所示:@attribute [Authorize] 当未经身份验证的用户尝试访问 Fetchdata 页面时,会执行 AuthorizeRouteView.NotAuthorized 委托属性,因此我们可以添加一些代码将用户重定向到同一个 okta 的登录页面进行身份验证。
  2. 将此代码放在 NotAuthorized 元素中,如下所示:

    <NotAuthorized> @{ var returnUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri); NavigationManager.NavigateTo($"login?redirectUri= {returnUrl}", forceLoad: true); } </NotAuthorized>

这将检索您尝试访问的最后一个页面的 url,即 Fetchdata 页面,然后导航到执行密码质询的 Login Razor 页面,即用户被重定向到 okta 的登录页面进行身份验证。

用户通过身份验证后,他被重定向到 Fetchdata 页面。

最后但同样重要的是,在 Fetchdata 页面顶部添加以下内容: @page "/authorization-code/fetchdata"

请注意,Fetchdata 组件已经有一个@page 指令,这个是第二个。多个路由模板在 Blazor 中是合法的……但我为什么要添加它?这是因为从 okta 传递到我们的应用程序的返回 url 是 "/authorization-code/fetchdata",而不是我们可能预期的“/fetchdata”,因为我们从导航管理器中提取的 returnUrl 是“fetchdata”。我不确定我是否理解“/authorization-code/”的作用,以及为什么要对我们强制执行。我真的没有时间去调查。但是,okta 需要此 url 段,并且在我的代码和 okta 网站的仪表板中,任何不使用它的尝试都失败了。我可以在代码中去掉这个 url 段,但这不是问题。我只是想知道为什么我们需要提供它,这样我才能更好地处理它。如果您碰巧了解更多信息,请在此处报告,因为我不能花更多时间调查...

顺便说一下,文章中提供的解决方案绝不是完整的;我敢说,比较偏。

祝你好运……

【讨论】:

  • 哇,非常感谢。这里有很多东西要审查。我可能会有问题。我今天也有很多事情要做。但是,我会尽快回复您。再次感谢!!!
  • 更新:您在下面概述的身份验证更改有效。谢谢你,谢谢你,谢谢你。马上,它将我重定向到我的 okta 登录页面。但是,我在重定向回主页时遇到了问题。为了解决这个问题,我必须在我的 Issuer Url 末尾添加“/oauth2/default”。你没有那个。原来的文章做到了。我将尝试您在更新中建议的授权代码。好东西
  • 不,我没有。我已经使用了原始文章中的 url,但它不起作用,所以我尝试了我在他们的仪表板中获得的 url,它工作得非常好。我现在已经用 "/oauth2/default" 试过了,它也可以工作。我将更新我的答案以反映这一点,因此其他人不会在这里失败。如果你碰巧知道“/authorization-code/callback”的作用是什么,请在这里报告。 @Richard,如果它解决了您的问题,您介意将其标记为答案,以便其他人知道它很有用。
  • 更新 2:我的授权代码也能正常工作。所以谢谢。我按照你的要求做了。我还将从上面更新原始帖子以引用此答案,以便其他人可以正确设置。再次感谢您的所有帮助。我真的很感激。
  • 有没有办法取消登录/注销页面?我想转到我的 URL 并自动跳转到 Okta 并尝试 SSO。要么我将在我的企业集成机器上自动进行身份验证,要么我将使用 Okta 的 UI 登录。我会回来授权并进入主页(或返回 URL)。我的应用程序的用户不想看到我自己创建的登录页面,我不知道如何处理返回 URL
猜你喜欢
  • 2020-09-02
  • 2021-05-28
  • 2020-05-15
  • 1970-01-01
  • 2020-09-19
  • 2020-09-26
  • 2020-09-30
  • 1970-01-01
  • 2020-03-25
相关资源
最近更新 更多