dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.37k stars 9.99k forks source link

Blazor App, individual Accounts and Authorization #52800

Closed famda closed 8 months ago

famda commented 10 months ago

Hi,

I'm trying to implement a BFF with the new features of Identity (dotnet 8) using the new template Blazor App (using Auto Interactive render modes).

The current template (when including the respective auth option), creates everything and uses ef core on the "host" project. However, the idea was to use the identity endpoints on a separate api project (BFF).

API (identity) <- Blazor App (server) <- Blazor (client)

Another issue that I've found is to flow claims (roles, custom claims) to the client (does it require to have a custom endpoint on the api to serve this data? - the cookie/token have all that data in it). (There is an issue opened with a PR on the blazor-samples repo but the proposed PR for standalone wasm w/ identity seems a hack).

The current documentation doesn't help with the available samples/information.

Can you please provide guidance/sample for this, please?

julioct commented 10 months ago

I was trying a similar scenario:

Blazor App (SSR) With Identity UI -> API (Identity)

Other than start modifying Login.razor, Register.razor and problably a few other razor components to talk to the Identity endpoints in the API project, I don't know what else could/should be done.

Would love some advice, or ideally a good sample on the right way to proceed.

Kumima commented 10 months ago

@famda @julioct I'm here to discuss, providing help and request too. I can't promise that I'm telling the right thing. I've explored the identity part for Blazor for a long time.

First, what you want to implement is more suitable for WASM Standalone, because I believe one of the main advantages of Blazor is you don't need to write API. For server mode and SSR you can get access to all stuff of the server without sending API. So, what you are doing is more like WASM Standalone.

What I understand:

If you want to implement identity logic through API project, you must do things like WASM. You can check the sample. The most important part is how to implement the AuthenticationStateProvider. You have to send request to your API Backend to get the user info, and store it into AuthenticationStateProvider. This is the weird part, why don't we need to do this in default template?

For default template, the authentication state is auto assigned internally. I believe it's because the PersistingRevalidatingAuthenticationStateProvider implements the RevalidatingServerAuthenticationStateProvider which implements the ServerAuthenticationStateProvider. And the authentication state is set through asp.net core/blazor pipeline. The cookie is read, and the user is set internally.

But if you place your identity logic in API Project, the AddAuthentication stuff is moved into your API Project. The Blazor Project does not know how to handle your cookie/token requested from your API Project, it can't set the user automatically. That's why you have to bring cookie/token to request user info and set AuthenticationStateProvider.

This creates complex and breaks the advantage of Blazor. It's just like a JS/WASM Frontend + .NET Backend.

famda commented 10 months ago

Hi, The idea of having the BFF is that you can have the API completely separated from the "UI" project(s). @davidfowl has his awesome project that explains what is meant to be achieved (here)

The idea of having the DbContext (even on the "Host" project) is not the expected.

What I'm trying to achieve is to have the same setup but using the new identity endpoints, flow the claims of the user to the client and using the necessary AuthenticationStateProvider.

Kumima commented 10 months ago

I just have a quick look of the TodoApi project. I think the identity process of it is much more complex than this sample. Looks like this sample is enough for your scenario. It does use the new identity endpoints. And the TodoApi Frontend even does not use AuthenticationStateProvider

Kumima commented 10 months ago

I do think there is difficulty for auto mode. For standalone WASM, HttpClient is used as Browser Fetch, you can get/set cookie to get user info from API. But when the render mode is Server, you need to add cookie/token into HttpClient Request payload.

famda commented 10 months ago

The repo has a dotnet8 branch and it's actually well designed and it's not that complex.

The only missing part are the actual claims flowing and the correct AuthenticationStateProviders and PersistentComponentState both on server and the client.

Maybe, @halter73 or @SteveSandersonMS can also provide some guidance on properly design this. 😀

halter73 commented 10 months ago

The ASP.NET Core Identity system is designed to authenticate a single web application. You could theoretically give the same app name and data protection keys to your blazor frontend and API backend, and then they could decrypt the same cookie/token and read the claims, but we recommend using either a cloud or self-hosted OIDC service for BFF.

Take a look at https://learn.microsoft.com/en-us/aspnet/core/security/how-to-choose-identity-solution?view=aspnetcore-8.0#identity-vs-oidc-server to see what our recommendations are in this area.

If you do want to use and OIDC server to do BFF, take a look at the Blazor OIDC BFF sample I've been working on at https://github.com/dotnet/blazor-samples/pull/137. We hope to get a full article using that sample published soon, but I can answer questions about it in the meantime.

If you want just to authenticate a Blazor WASM app with MapIdentityApi without making authenticated calls to a separate backend, take a look at https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-identity?view=aspnetcore-8.0

And if you're using the new Blazor template with auto interactivity, I recommend just using the "Individual Auth" template. This doesn't do BFF, but that isn't a supported scenario for ASP.NET Core Identity.

julioct commented 10 months ago

@halter73 Thanks a lot for all these great Identity improvements in ASP.NET Core 8.

Do you have any comments on https://github.com/davidfowl/TodoApi?

I have a PR here to get it all updated to .NET 8 RTM goodness: https://github.com/davidfowl/TodoApi/pull/90

It uses the latest Blazor bits and the new identity endpoints, so I'm hoping to use it as a reference sample.

famda commented 10 months ago

Hi @halter73, I've read all those documents (except the data protection keys - I've learned something new :)). The architecture of my example is actually similar to the TodoApi (which @julioct was kind enough to update to the latest RTM on his PR).

I'm also curious on your comments on this.

bcheung4589 commented 9 months ago

Bit late to the party but have a look at my project PortalForgeX

Blazor 8 - AutoRenderMode, so its mixed.

binraider commented 9 months ago

You should look at Damien Bods website and github Repo, as he has a lot to say about this topic and is a contributor to asp.net. He creates a lot of projects using BFF in different configurations

mkArtakMSFT commented 8 months ago

Closing as it seems no further action is pending here from the team.