Blazor(服务器端)和Okta

Blazor(服务器端)和Okta,blazor,okta,blazor-server-side,Blazor,Okta,Blazor Server Side,我目前正在通过这篇文章将okta集成到Blazor服务器端应用程序中 我现在收到“对不起,这个地址什么都没有” 我希望有人能对我的问题提出建议 或者有人知道将okta集成到Blazor服务器端应用程序的示例吗? 请让我知道 任何帮助都将不胜感激。我完全在转动我的轮子 以下是我的okta常规设置: 下面是我解决方案中的代码(我反复阅读了这篇文章,以确保它是正确的。但我想我可能错过了一些东西。) 启动配置服务 services.AddAuthorizationCore();

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

我现在收到“对不起,这个地址什么都没有”

我希望有人能对我的问题提出建议

或者有人知道将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>
<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.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>
<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> ```




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

```
当您单击“登录”锚元素时,路由器找不到“身份/帐户/登录”路径,其结果是显示对不起,此地址没有任何内容。

。当然,您没有被定向到okta网站,也没有进行身份验证,对吗

我无法理解她为什么这样设置AuthorizeView组件。然而,在我看来,她的整篇文章是由一个市政委员会设计的,并且是由多余的代码片段组合而成的。然而,这超出了本答案的范围

解决方案
  • 创建一个名为LoginDisplay(LoginDisplay.razor)的组件,并将其放置在共享文件夹中。此组件在MainLayout组件中使用

    
    注销
    

    将LoginDisplay组件添加到MainLayout组件,就在About的上方 锚元素,像这样
    
    

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

    Login.cshtml.cs 这段代码为您在Startup类中定义的Open Id Connect身份验证方案启动质询

  • 创建一个注销页面Logout.cshtml(Logout.cshtml.cs),并将其放置在Pages文件夹中: Logout.cshtml.cs
  • 使用Microsoft.AspNetCore.Authentication
    
    
    公共类LogoutModel:PageModel
    {
    公共异步任务OnGetAsync()
    {
    等待HttpContext.SignOutAsync();
    返回重定向(“/”);
    }
    }
    
    此代码将您注销,并将您重定向到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>
    
    不要尝试使用我的设置,因为我已经更改了它们。。。 Startup类中的代码是正确的,但是您可能需要添加一些名称空间引用,可能是我添加的nuget包,等等

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

    更新 请注意,按此处所做的方式创建登录机制不会使您的应用程序比以前更安全。任何用户都可以访问您的web资源,而无需登录。为了保护网站的部分安全,您还必须实施授权。按照惯例,经过身份验证的用户有权访问受保护的资源,除非实施了其他措施,如角色、策略等。以下演示如何保护未经授权的用户的Fetchdata页(同样,经过身份验证的用户被认为有权访问Fetchdata页)

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

    {
      "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": "*"
    }
    
    
    @{
    var returnUrl=
    NavigationManager.ToBaserRelativePath(NavigationManager.Uri);
    NavigationManager.NavigateTo($”登录?重定向URI=
    {returnUrl},forceLoad:true);
    }
    

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

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

    最后,在Fetchdata页面顶部添加以下内容:
    @page”/authorization code/fetchdata“

    请注意,Fetchdata组件已经有一个@page指令,这是第二个指令。Blazor中的多个路由模板是合法的……但我为什么要添加它呢?这是因为从okta传递到我们的应用程序的返回url是
    “/authorization code/Fetchdata”
    ,而不是“/Fetchdata”,正如我们所料,因为我们从导航管理器中提取的returnUrl是“fetchdata”。我不确定我是否理解“/authorization code/”的角色,以及为什么要强制执行。我真的没有时间调查。但是,okta需要此url段,任何尝试不使用此url段的尝试都失败了,无论是在我的代码中还是在okta网站的仪表板中。我可以在代码中删除此url段,但这不是问题。我只想知道我们为什么需要提供它,所以我可以如果你碰巧