在 c# 中使用 Okta 和 Blazor,LocalRedirect() 陷入循环并出现错误“Too Many Requests”

问题描述 投票:0回答:1

我尝试在我的应用程序中实现 Okta 登录。在编辑真正的应用程序之前,我正在运行一个测试应用程序来弄清楚它。我加载了 url,它按应有的方式通过 Okta 进行身份验证。然后它会在页面上显示“正在加载...”几秒钟,然后给出错误:

LocalRedirect(redirectUri) 应重定向到“/”。相反,它再次循环回到登录函数。

LoginController.cs:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;

namespace TestOktaLogin.Controllers {
    public class LoginController : Controller {
        [HttpGet("Login")]
        public IActionResult Login([FromQuery] string returnUrl) {
            var redirectUri = returnUrl is null ? "/" : "/" + returnUrl;

            if (User.Identity.IsAuthenticated) {
                return LocalRedirect(redirectUri); //It does not return. It just reloads the function.
            }

            return Challenge();
        }

        // This is the method the Logout button should get to when clicked.
        [HttpGet("Logout")]
        public async Task<ActionResult> Logout([FromQuery] string returnUrl) {
            var redirectUri = returnUrl is null ? Url.Content("~/") : "/" + returnUrl;

            if (!User.Identity.IsAuthenticated) {
                return LocalRedirect(redirectUri);
            }

            await HttpContext.SignOutAsync();

            return LocalRedirect(redirectUri);
        }
    }
}

RedirectToLogin.razor.cs:

using Microsoft.AspNetCore.Components;

namespace TestOktaLogin.Components {
    public partial class RedirectToLogin : ComponentBase {
        [Inject] public NavigationManager Navigation { get; set; }

        protected override async Task OnInitializedAsync() {
            var returnUrl = Navigation.ToBaseRelativePath(Navigation.Uri);

            Navigation.NavigateTo($"Login?returnUrl={returnUrl}", true);
        }
    }
}```




Home.razor, which is the default to "/":

@页面“/”

@属性[授权]

首页

世界,你好!

欢迎使用您的新应用程序。```

程序.cs:

using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using TestOktaLogin.Components;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddMvc();

builder.Services.AddAuthentication(authOptions => {
    authOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    authOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    authOptions.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    authOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddOpenIdConnect(oidcOptions => {
    oidcOptions.ClientId = builder.Configuration["Okta:ClientId"];
    oidcOptions.ClientSecret = builder.Configuration["Okta:ClientSecret"];
    oidcOptions.CallbackPath = "/authorization-code/callback";
    oidcOptions.Authority = builder.Configuration["Okta:Issuer"];
    oidcOptions.ResponseType = "code";
    oidcOptions.SaveTokens = true;
    oidcOptions.Scope.Add("openid");
    oidcOptions.Scope.Add("profile");
    oidcOptions.TokenValidationParameters.ValidateIssuer = false;
    oidcOptions.TokenValidationParameters.NameClaimType = "name";
}).AddCookie();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) {
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // 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.UseAntiforgery();

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

app.MapControllers();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

如果我需要上传任何其他代码,请告诉我。谢谢您的帮助!

c# .net blazor okta
1个回答
0
投票

您有以下循环:

User -> Login -> Okta -> LoginController -> LocalRedirect -> Home (Authorized)
  ^                                                                  |
  |__________________________________________________________________|

发生该循环是因为在

LocalRedirect
之后,用户被重定向回登录过程而不是主页。

Login
操作中,您将检查用户是否已通过身份验证,然后执行
LocalRedirect

当用户未经过身份验证时,
Challenge
方法已正确放置以启动身份验证过程。

循环并非源自

Challenge
本身,但如果在用户经过身份验证后可能会发生:它们被重定向回需要身份验证的路由,并且
Authorize
属性
将它们重定向回登录页面,因为它无法识别用户已通过身份验证。

另请参阅“ASP.NET Core 身份验证概述

您的

LoginController
中发出
Challenge
的具体部分:

if (User.Identity.IsAuthenticated) {
    return LocalRedirect(redirectUri); // If authenticated, redirect to the return URL or home
} else {
    return Challenge(); // If not authenticated, initiate the authentication process
}

潜在的问题可能与

LocalRedirect(redirectUri)
行有关:如果
redirectUri
在某种程度上配置错误并重定向回最终再次重定向到
/Login
的页面(就像
RedirectToLogin
组件可能会做的那样),这会创建一个循环。该循环将继续下去,直到浏览器由于重定向过多而停止它,从而导致您看到的“
Too Many Requests
”错误。

此外,

Program.cs
中的中间件可能配置错误,未正确维护身份验证状态或在
Authorize
中使用不正确的
Home.razor
属性用法。

要调试此问题:

  • 确保
    redirectUri
    在身份验证后是有效且可访问的路由。
  • 确认
    Home
    页面识别身份验证状态并且不会重定向回
    Login
    页面。
  • 验证
    Program.cs
    中的身份验证中间件是否正确配置为处理登录后的身份验证状态。
  • 使用日志记录来跟踪重定向流,以准确查看重定向循环发生的位置。

如果这些检查全部正确,则应该打破循环,并且用户应该在身份验证后正确重定向到主页。


确保您的

Login
操作在身份验证成功后不会再次被调用。
这应该通过调整
redirectUri
逻辑并确保
Challenge
仅在必要时出现来完成。

您的

LoginController
将是:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;

namespace TestOktaLogin.Controllers {
    public class LoginController : Controller {
        [HttpGet("Login")]
        public IActionResult Login([FromQuery] string returnUrl) {
            // Make sure returnUrl is not causing a loop back to this action
            var redirectUri = Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl)
                ? returnUrl
                : "/";

            if (User.Identity.IsAuthenticated) {
                // Redirect to the original requested resource or home if authenticated
                return LocalRedirect(redirectUri);
            }

            // Only issue a challenge if the user is not authenticated
            return Challenge();
        }

        // Rest of your code
    }
}

您现在需要检查以确保

returnUrl
是本地的,而不是
null
或空,以防止重定向到可能导致循环的未经授权的路由。

对于

RedirectToLogin
组件,请确保仅在用户未经身份验证的情况下使用它,否则,它也可能会导致循环。

您还需要确保您的 OpenID Connect 配置和

Authorize
中的
Home.razor
属性使用设置正确,以防止未经授权的访问,这可能会导致重定向回登录过程。

© www.soinside.com 2019 - 2024. All rights reserved.