asp.net-coreasp.net-identitymaui

Using ASP.Net Core Identity for Razor page web app and MAUI app


I've got a razor pages/mvc web app that uses ASP.Net Core Identity for authentication and authorization. I'm starting to develop a mobile app version of the site using MAUI and wanting to access many of the same endpoints (some of them are WebAPI endpoints for page javascript) but am struggling to get the web app authentication working alongside the IdentityApiEndpoints to get tokens for the MAUI app. First question is whether co-mingling the two authentications is the correct way of doing things?

Assuming this is a workable way of doing the authentication, how do I get this to work with both.This is what I originally had:

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultUI()
    .AddDefaultTokenProviders();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

I tried using the new AddIdentityApiEndpoints:

builder.Services.AddIdentityApiEndpoints<ApplicationUser>()
    .AddRoles<IdentityRole>()   //Needs to come before the EntityFramework stores to work
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultUI()
    .AddDefaultTokenProviders();


...
app.MapIdentityApi<ApplicationUser>().AllowAnonymous();

This mostly works but I can't seem to add redirection to the login page - i.e. if someone navigates to the main page without being logged in, it used to redirect to the login page but no longer does. I also tried:

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddApiEndpoints()
    .AddDefaultUI()
    .AddDefaultTokenProviders();

but when I try login with postman, I get this error:

System.InvalidOperationException: 'No sign-in authentication handler is registered for the scheme 'Identity.Bearer'. The registered sign-in schemes are: Identity.Application, Identity.External, Identity.TwoFactorRememberMe, Identity.TwoFactorUserId. Did you forget to call AddAuthentication().AddCookie("Identity.Bearer",...)?'

How can I configure this to still have the redirection to the login screen?


Solution

  • Posting my solution in case it helps anyone else. I needed to add the bearer token as a authentication scheme like this:

    builder.Services.AddAuthentication()
        .AddBearerToken(IdentityConstants.BearerScheme);
    
    builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddApiEndpoints()
        .AddDefaultUI()
        .AddDefaultTokenProviders();
    

    I then needed to allow anonymous access to those API endpoints:

    app.RegisterApiEndpoints();
    app.MapIdentityApi<ApplicationUser>().AllowAnonymous();
    

    Finally I needed to add a custom policy that accepted the bearer token and the cookie to the endpoints that were going to be accessed with the bearer token. The answer here really helped with that: Why am I redirected to Account/Login page when using WebApi and AspIdentityCore beside JwtBearer in dotnet 7?