I'm working on implementing OAuth in an ASP.NET Core (using .NET 5, Razor Pages) application. I'm encountering an error, but I don't quite understand what it's telling me.
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. 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. 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:
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)
Startup.cs ConfigureServices()
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()
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!
options.CallbackPath
defined in Startup.cs ConfigureServices(), under services.AddOAuth().
options.CallbackPath
is defined ahead of time.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). 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 = new PathString("/Auth/Login");
If you have a controller action bound to /Auth/Login
, this should be the source of the issue.
The vale of options.CallbackPath
doesn't have to match any controller action. 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.