【问题标题】:ASP.NET Core OAuth2 implementation using company provider. Exception: The oauth state was missing or invalid使用公司提供程序的 ASP.NET Core OAuth2 实现。例外:oauth 状态丢失或无效
【发布时间】:2021-12-27 02:31:32
【问题描述】:

我正在努力在 ASP.NET Core(使用 .NET 5,Razor Pages)应用程序中实现 OAuth。我遇到了一个错误,但我不太明白它在告诉我什么。

背景资料

我还没有让 OAuth 实现工作,所以即使我能够让它工作并解决这个错误,我也不相信我已经完美地设置了一切。如果您对我可以改进的事情有任何建议,将不胜感激!

作为参考,我只是尝试使用 OAuth 几天,而且我之前没有任何身份验证/授权方面的经验。不过,我已经阅读了一些指南,我将在本文末尾提及。

我已包含以下详细信息:

  • 异常消息和堆栈跟踪
  • 我的代码
  • 我的想法
  • 参考文献

错误

Exception: The oauth state was missing or invalid.

堆栈跟踪:

System.Exception: An error was encountered while handling the remote login.
 ---> System.Exception: The oauth state was missing or invalid.
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

我的代码

  • 我不确定与我公司实施 OAuth 相关的信息有多私密,因此为了安全起见,我省略了可以识别公司的细节。

Startup.cs ConfigureServices()

  • 仅包括与 OAuth2 相关的部分
public void ConfigureServices(IServiceCollection services)
{
    // OAuth2 Authentication 

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = "MyCompanyAuthenticationScheme";
    }).AddCookie(options =>
    {
        options.Cookie.IsEssential = true;
    }).AddOAuth("MyCompanyAuthenticationScheme", options => 
    { 
        options.ClientId = Configuration["Company:ClientId"];
        options.ClientSecret = Configuration["Company:ClientSecret"];
        options.CallbackPath = new PathString("/Auth/Login");
        
        options.AuthorizationEndpoint = "...";
        options.TokenEndpoint = "...";
        options.UserInformationEndpoint = "...";

        // todo: are all three of these necessary?
        options.Scope.Add("loginAccountInfo");
        options.Scope.Add("contactInfo");
        options.Scope.Add("employeeInfo");

        options.SaveTokens = true;

        // todo: are the jsonKeys defined in the above Scopes? follow up when you have a better understanding of how these work, or if the MapJsonKey lines are even necessary
        options.ClaimActions.MapJsonKey(ClaimTypes.Name, "firstName");
        options.ClaimActions.MapJsonKey(ClaimTypes.Email, "emailAddress");
    });
}

Startup.cs 配置()

  • 再次只包含相关的代码部分
  • 重要的是我确实包含app.UseAuthentication()
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseAuthentication();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
    });
}

授权控制器:

[AllowAnonymous]
[Route("[controller]/[action]")]
public class AuthController : Controller
{
    [HttpGet]
    public IActionResult Login(string returnUrl = "/")
    {
        if(!User.Identity.IsAuthenticated)
            return Challenge(new AuthenticationProperties() { RedirectUri = returnUrl});

        return Forbid();
    }
}

我认为这是与 OAuth 相关的所有相关代码,但如果您认为我需要包含更多详细信息,请告诉我!

我的想法

  • 我认为问题在于我在 Startup.cs ConfigureServices() 中定义的 options.CallbackPath,位于 services.AddOAuth() 下。
    • 我看到一些帖子详细说明我不需要设置此变量,但在这些帖子中,他们似乎正在为具有提前定义了options.CallbackPath 的 NuGet 包。
    • 我还看到一些信息说 options.CallbackPath 由 OAuth 中间件在内部使用,并且它不对应于控制器操作(这意味着我不需要我的 Auth 控制器及其登录操作) .但是,如果我删除定义 options.CallbackPath 的行,我会收到另一个错误,说它没有定义,这让我相信这是非常必要的。

参考文献

【问题讨论】:

  • 据我所知,状态是一个代码,用于检查服务器是否是我们想要验证的正确服务器。我建议您可以先检查服务器返回的响应是否包含此统计代码。如果您的身份提供者没有将此统计信息返回给客户端。它会导致这个错误。此外,通常需要进行此统计检查以提高应用程序的安全性。但如果您认为您的连接是安全的,您可以禁用此检查。

标签: c# asp.net asp.net-core oauth-2.0 oauth


【解决方案1】:

options.CallbackPath = new PathString("/Auth/Login");

如果您有绑定到/Auth/Login 的控制器操作,这应该是问题的根源。

options.CallbackPath 的值不必匹配任何控制器操作。它是中间件接收身份提供者回答的内部路由。 您可以简单地将/callback 分配为其值或与现有路由不匹配的任何其他值

【讨论】:

  • 感谢您的提示!我试过了,确实让我的程序继续克服这个错误,这很棒。不幸的是,当我重定向到授权端点时,我得到了一个 400 状态代码,我认为这是在 localhost 上运行应用程序的一个问题,所以我可能不得不在这方面与我的组织进行更多的合作。谢谢!
猜你喜欢
  • 2021-04-26
  • 2019-02-02
  • 1970-01-01
  • 2021-11-06
  • 2023-02-15
  • 2023-01-31
  • 2017-09-22
  • 2020-04-14
  • 2015-05-07
相关资源
最近更新 更多