Home > Back-end >  Submit Form return HTTP ERROR 400 for logged in User with non DefaultAuthenticateScheme
Submit Form return HTTP ERROR 400 for logged in User with non DefaultAuthenticateScheme

Time:03-16

I am building MVC Core app that has multiple logins for different users:

  1. CMSUsers.
  2. ClientUsers

Each Users' type is stored in different sql server table. As I am using Cookie Authentication without ASP.NET Core Identity, I created the following schemes:

  1. CMS
  2. Client

I have registered the schemes in the Startup.cs file as:

public void ConfigureServices(IServiceCollection services)
{
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    services.AddAuthentication("CMS")
        .AddCookie("CMS", o => { o.LoginPath = "/CMS/Login"; })
        .AddCookie("Client", o => { o.LoginPath = "/Client/Login"; });

    services.AddControllersWithViews();
}

I have decorated Controller Actions with its shceme and required Role as needed:

[Authorize(AuthenticationSchemes = "Client", Roles = "AdminRole")]

Some Actions are not decorated with Authorize as they are used by all users (Logged in or Logged out).

The Problem: When any of the Users' type (CMS or Client, wether they are logged in or not) try to submiting a simple form:

<form action="/Home/Search" method="post">
  <div >
     @Html.AntiForgeryToken();
      <input type="text"  name="Search"  value="">
      <button type="submit">Search</button>
  </div>
</form>

and the target actions is:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Search(SearchViewModel vm)
{
    vm.Results = ""; //Do some work
    return View("Search", vm);
}

only CMSUsers manage to reach the target action, because CMS scheme is the default scheme as registered in Startup.cs:

    services.AddAuthentication("CMS")
        .AddCookie("CMS", o => { o.LoginPath = "/CMS/Login"; })
        .AddCookie("Client", o => { o.LoginPath = "/Client/Login"; });

If I change the default scheme to Client, only Client Scheme will manage to call the target action and CMS will get error 400.

Also, if I remove the [ValidateAntiForgeryToken] from the target action, all users can submit the form successfully.

What am I missing?

Or is it a single scheme authentication only?

CodePudding user response:

After searching the web, adding the following to the Startup.cs solved the problem.

    app.Use(async (context, next) =>
    {
        var principal = new ClaimsPrincipal();
        var result1 = await context.AuthenticateAsync("CMS");
        if (result1?.Principal != null)
        {
            principal.AddIdentities(result1.Principal.Identities);
        }

        var result2 = await context.AuthenticateAsync("Client");
        if (result2?.Principal != null)
        {
            principal.AddIdentities(result2.Principal.Identities);
        }

        context.User = principal;
        await next();
    });
  • Related