Skip to content

adamfoneil/ApiAuthDemo

Repository files navigation

This was inspired by another Blazor project sample-blazor8-auth-ms. I wanted to make something based on my opinions on certain things, and that gets closer to a production use case -- with some EF Core action and a minimal CRUD experience with a Radzen grid. This wouldn't be possible without Dave's original project, as there were some critical Blazor WebAssembly parts I couldn't figure out on my own. I do find it surprising that there's not really a pit of success when implementing a Blazor API that requires authentication. The parts I was missing incidentally, were CookieHandler and some special HttpClient initialization -- both in the Client/Program.cs and the main app Program.cs. I still don't understand why this code needs to be in both projects.

Part of the issue is I was trying really hard at first to use Refit for the API client. I love Refit's productivity, but it doesn't align with Blazor authentication because Refit wants to treat the HttpClient as a singleton. Singletons don't have access to ASP.NET authentication infrastructure, so I kept running into roadblocks there. I went my own way with ApiClientBase, and its derived class ApiClient. This is also a little different from Dave's project because I wanted my API calls to be exposed through an interface, not called directly on HttpClient. (In this case, when I say "interface" I mean a class that's encapsulating some stuff, not an actual interface, which I feel is not necessary here.)

Speaking of the API, the endpoints are here in Program.Endpoints.cs. This is using minimal APIs and EF Core for the underlying data access. The one little oddity you might notice is this Save extension method used here. I'd prefer to use a single POST to handle both inserts and updates.

This all comes together in Widgets/Page.razor, which has the Radzen grid and its infrastructure. I do a couple unique things here to minimize boilerplate -- all centered around this GridHelper. This is ultimately based on some work of mine in another project that encapsulates some opinionated ways I use Radzen: Radzen.Components. This gives the "are you sure" dialog when deleting a row, and simplifies the core CRUD operations as much as possible IMO.

Note, this project contains all the regular Blazor template stuff, which I am too impatient to remove.

image

Time Zone Support

My eventual use case for this in production is in a multi-tenant app where auditing and permissions depend on knowing custom properties of the user, in this case ApplicationUser. One way to demo custom user properties (without adding true multi-tenant support to this app), was to add time zone support to the auditing features.

I've accomplished this by: