简体   繁体   English

使用公司提供程序的 ASP.NET Core OAuth2 实现。 异常:oauth 状态丢失或无效

[英]ASP.NET Core OAuth2 implementation using company provider. Exception: The oauth state was missing or invalid

I'm working on implementing OAuth in an ASP.NET Core (using .NET 5, Razor Pages) application.我正在 ASP.NET Core(使用 .NET 5、Razor Pages)应用程序中实现 OAuth。 I'm encountering an error, but I don't quite understand what it's telling me.我遇到了一个错误,但我不太明白它在告诉我什么。

Background Info背景信息

I haven't gotten the OAuth implementation to work yet, so even if I am able to get it to work and resolve this error, I'm not convinced that I have everything set up perfectly.我还没有让 OAuth 实现工作,所以即使我能够让它工作并解决这个错误,我也不相信我已经完美地设置了一切。 If you have any tips on things I could improve it would be greatly appreciated!如果您对我可以改进的事情有任何建议,将不胜感激!

For reference, I've only been trying to work with OAuth for a few days, and I don't have any prior experience in authentication/authorization.作为参考,我只尝试使用 OAuth 几天,并且我之前没有任何身份验证/授权经验。 I have read a few guides though, which I'll mention at the end of my post here.不过,我已经阅读了一些指南,我会在我的帖子末尾提到这些。

I've included details on the following:我已经包含了有关以下内容的详细信息:

  • the exception message and the stack trace异常消息和堆栈跟踪
  • my code我的代码
  • my thoughts我的想法
  • references参考

The Error错误

Exception: The oauth state was missing or invalid.

Stack Trace:堆栈跟踪:

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)

My Code我的代码

  • I'm not sure how private the information relating to my company's implementation of OAuth is, so I've omitted details that could identify the company just to be safe.我不确定与我公司实施 OAuth 相关的信息有多私密,因此为了安全起见,我省略了可以识别公司的详细信息。

Startup.cs ConfigureServices() Startup.cs ConfigureServices()

  • only including portion that relates to OAuth2仅包括与 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 Configure() Startup.cs 配置()

  • again only included relevant sections of code再次只包含相关的代码部分
  • the important piece is that I do include app.UseAuthentication()重要的是我确实包含了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();
    });
}

Auth controller:验证控制器:

[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();
    }
}

I think this is all of the relevant code relating to OAuth, but if you think I need to include more details let me know!我认为这是与 OAuth 相关的所有代码,但如果您认为我需要包含更多详细信息,请告诉我!

My Thoughts我的想法

  • I think the issue is something with my options.CallbackPath defined in Startup.cs ConfigureServices(), under services.AddOAuth().我认为问题出在我在 Startup.cs ConfigureServices() 中定义的options.CallbackPath中,在 services.AddOAuth() 下。
    • I've seen some posts detailing that I don't need to set this variable, but in those posts it seems that they're implementing OAuth for a provider (such as Google, GitHub, Facebook, etc) that has a NuGet package in which options.CallbackPath is defined ahead of time.我已经看到一些帖子详细说明我不需要设置这个变量,但在这些帖子中,他们似乎正在为具有 NuGet 包的提供者(例如 Google、GitHub、Facebook 等)实施 OAuth提前定义了哪些options.CallbackPath
    • I've also seen some information saying that options.CallbackPath is used internally by the OAuth middleware, and that it doesn't correspond to a controller action (which means I wouldn't need my Auth controller and its Login action).我还看到一些信息说options.CallbackPath由 OAuth 中间件在内部使用,并且它不对应于控制器操作(这意味着我不需要我的 Auth 控制器及其登录操作)。 However, if I remove the line defining options.CallbackPath , I get another error saying that it isn't defined, leading me to believe that it is very necessary.但是,如果我删除定义options.CallbackPath的行,我会收到另一个错误,指出它未定义,这让我相信这是非常必要的。

References参考

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

If you have a controller action bound to /Auth/Login , this should be the source of the issue.如果您有一个绑定到/Auth/Login的控制器操作,这应该是问题的根源。

The vale of options.CallbackPath doesn't have to match any controller action. options.CallbackPath的值不必匹配任何控制器操作。 It is an internal route where the middleware receives the answer of the Identity provider.它是中间件接收身份提供者答案的内部路由。 You can simply assign /callback as its value or any other value that doesn't match an existing route您可以简单地将/callback指定为其值或与现有路由不匹配的任何其他值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM