I heard that for .NET8 Microsoft gifted us with a totally "fixed" authentication and authorisation setup.
Now, when I create a Blazor application from the templates, it scaffolds out a whole bunch of user admin pages including login etc., and there is a database migration you can run to create the associated backend support for it. And it works great, right out of the box I can add users, login, and protect pages with the [Authenticate] flag.
The first problem I have is I don't want to use Entity Framework, and I don't want to use MS SQL Server. But that's trouble for another time.
My wider problem is this out-of-the-box experience provided in the Blazor project template does not attempt to address one of the typical architectures where you have a Blazor app for the front-end, a database for the backend, and an API that sits in between to receive and reply to requests.
In this scheme, which is the one that I want to use, the identity should not be handled directly by the Blazor app. Instead, it is really the WebAPI that should do it since it is the one who has access to the database backend.
But if I use the templates to create a .NET8 API project, Microsoft sticks with the previous AzureAD authentication method (from previous .NET versions) and does not use any of the new Identity stuff that you get provided with the Blazor application.
OK, so perhaps, I can see what they are doing in the Blazor App and implement all that on the API side instead. But now I am wondering if I am going against the grain here, and doing something which Microsoft does not intend. Essentially, I am worried I am lost at Sea and doing something wrong.
There is the further complication that even if I implement all that identity in the API, I still need to return some kind of identity object to the Blazor app, since it also needs to know if the user login was OK and what roles they have. I can imagine some ways that I could call an API endpoint to login from the Blazor app and return a suitable identity object to the Blazor app. But what about the potential for middle-man attacks here where someone would send their own identity object. Is it protected because of the https:// connection between the Blazor App and the WebAPI?
My question in summary: Is my setup of WebAPI for the identity, return the identity object to Blazor, a typical solution or am I down the wrong path with this?
I have always asked myself this very same question: why Microsoft templates and even documentation offer so little for those who want a more production-ready system?
The approach I have settled on for a while now is to:
Providing a full explanation of how to do the above is beyond the scope of a SO answer... if you can't find it I can try to put of a blog post together.
I hope this is at least useful to push you in the right direction.
UPDATE: this is my attempt to provide more guidance on how to proceed.
This is the function I use to extract all the important information into a record we call BackendSecurityContext:
public class EasyAuthHeadersAzureFunctionsSecurityContextFactory : IAzureFunctionsSecurityContextFactory
{
public const string HeaderName_PrincipalID = "x-ms-client-principal-id";
public const string HeaderName_PrincipalName = "x-ms-client-principal-name";
public IBackendSecurityContext CreateSecurityContext(IEnumerable<ClaimsIdentity> claimsIdentities, ImmutableDictionaryOfSet<string, string> httpRequestHeaders)
{
// Supporting documentation can be found here: https://docs.microsoft.com/en-us/azure/app-service/configure-authentication-user-identities#access-user-claims-in-app-code
var idStr = httpRequestHeaders[HeaderName_PrincipalID].SingleOrDefault();
var name = httpRequestHeaders[HeaderName_PrincipalName].SingleOrDefault();
var result = new BackendSecurityContext(
idStr is null ? null : Guid.Parse(idStr), // PrincipalID
name, // PrincipalName
!string.IsNullOrEmpty(idStr), // IsAuthenticated
[], // PrincipalClaims
ImmutableListWithSequenceEquality<string>.Empty // Roles
);
return result;
}
}
Note: in my opinion, this should all be covered by a single Microsoft documentation page as an end-to-end guide to serious/production-ready development and deployment of a web app, but I have never found such a page. If someone does, they should just replace my answer with a link! :-)