-
Notifications
You must be signed in to change notification settings - Fork 10.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ASP.NET Core SPA Templates Need Better Options for Authentication #42158
Comments
+ 1 I don't even know why you would need identity server when starting out with a web project. It's overkill and requires licensing. WebApp with internal API I wish there was a SPA template with session cookie authentication, CSRF protection, Microsoft+Google federated login and scaffolded UI where you change everything, even the routes. Public API If you want to offer a public API it's trivial to implement client credentials flow where the client credentials can be generated in the web app (usually under "organization" or "account settings") |
+1 My recent experience with Blazor Server and scaffolding in Auth pages for customisation (which are .cshtml and not .razor pages) was not super fun or intuitive tbh 😅 It would have been really nice to have a template with a choice of provider(s) / auth components to be included in the template by default, and the support to scaffold in .razor pages (or even include some of the most important ones in the project by default) many people including myself have been confused that there is a project with pages which 'don't exist' in the solution until you scaffold them in. |
Pretty please with a bow on top! Would make the lives of working professional coders a lot easier. |
Also an example using openiddict which is free instead of identity server that would require a license for us to use. |
|
Even trying to do an API with auth, we are at a loss. A Laravel team tried and failed. Went back to Laravel. |
Honestly, Authentication is terrible. It's overcomplicated and slow. I implemented my own Authentication platform that completely hides the default built-in system, It's much faster than the stock system. I would share it but it's for a client and I don't own the rights to the code Authentication needs to be split out into its own libraries and not as part of the core of ASP.NET 6. |
That would be fantastic. |
Here are related issues I wrote (focused on the documentation, but certainly reflect the same concerns):
FWIW, we largely did our own work as well to make auth work in our Blazor WASM app and divorce from Identity Server, but I would much rather use a well supported foundation than what I built. Thanks @Grauenwolf for your suggestions. |
I'm happy that these are now concerns to the community. When standalone react and api application was introduced, I thought authentication would be improved upon but I rather saw complexity of third-party products like Identity Server, etc. I'm currently considering identify server 4 with OID client and still stuck with Net 5. |
I've managed to implement both username/password and the Microsoft Identity Web platform into a react SPA + backend API project. But it's been a hugely complicated task, and while it's great when I look back at how much I've learned, I doubt anyone wants to spend 6+ months digging into the deepest depths of ASP in order to come up with a production-ready implementation. The only reason I was able to do it is because Covid forced me to take a lot of time off work. If it's at all helpful, I have a working implementation here: Kiddo (Username/Password/Azure Ad web app). It uses JWTs instead of cookies, but on the server side it still uses the ASP Identity framework for managing usernames/passwords. I fully get that adding even a stripped down version of what I've managed to get working is a bit much for a template. There's simply so much boilerplate necessary simply to get the server-side API to work. That's not considering all of the UI components and integration with your site branding and design. I've wondered at the possibility that we (the community and ASP teams) could come up with a REST protocol to at least streamline the server-side component. From there it would be up to individual teams to write the actual SPA frontend that integrates with the API. |
Yes this is a must have, easy to use feature. We've switched few projects to other techs just because of this auth nightmare. |
Something has already started to happen in this matter: https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-preview-5/#jwt-authentication-improvements-automatic-authentication-configuration Is it the right direction? |
It is a good thing, but somewhat orthogonal to what we're talking about. The JWT improvements will help someone who already has a JWT based authentication provider running. But it's useless to someone who is starting from scratch and just needs an internal solution like ASP.NET Identity. |
Yeah @Grauenwolf is exactly right. Those changes look like they will make it marginally easier and cleaner for someone that's already written a complete JWT auth solution. For someone just starting out, it's extremely overwhelming to figure out what needs to be manually implemented, how to configure the built in stuff correctly, and then digging through all of the ASP library code so that when we have to re-implement something we are compatible with the rest of the ASP ecosystem. For example one area I had trouble with was getting a JWT implementation of ASP.NET Identity to co-exist with the Microsoft Identity Web platform. Getting it to work involved asking for help from the Microsoft Identity Web developers, sleuthing through the ASP code, and a ton of trial and error. There's still places I don't fully understand, and am afraid to touch because I may break what I somehow got working. |
@dajma00 Can you comment on this? If you have details it would be great! |
On the move from Laravel to .NET? |
@dajma00 On how the auth is much better in Laravel (for whatever scenario this team was trying to accomplish). |
Please consider porting scenarios from other major web frameworks like Laravel, Django, passport.js etc. A basic guideline will be helpful. |
@GuerrillaCoder you may want to take a look at the openiddict-samples repository:
A year ago, @blowdart and I informally discussed about potential options and having an equivalent of
Have you guys tried it? If so, what do you think of it? Is it something that could qualify as a good enough option for SPA/Blazor apps? |
I wasn't saying Laravel was better/easier for auth, I don't have much experience with that. I am consulting for a small team to do new projects in .NET and when they tried to start with .NET6 APIs, auth was their first obstacle and they couldn't get to speed for a month so they basically gave up temporarily. I understand that the team has no experience in .NET at all, so probably it wasn't entirely .NET's fault, but still auth in .NET6 needs to be easier and better explained. That is exactly the point here that auth needs to be something that new teams can embrace quickly, even if they are coming from other frameworks. We need to note that not all teams who want to embrace .NET have much or any experience with .NET. Some might be smarter and be able to deduce/learn from tutorials and websites. But many have difficulty understanding, especially when it comes to MS documentation. I myself, usually look at MS documentation for a few minutes and then move on to other search results quickly. I have produced many Blazor applications, all of them with auth and even mult-tenant apps but I cannot say with confidence how to go about using auth in .NET. Should I use Identity?, Duende? API authentication for public facing APIs, user websites, cookies vs JWT. I also understand there is a lot to cover here but when your audience is large and varied, you have to cater to all levels of programmers, not just the best ones. So that is where initial templates can be helpful and as more experience is gained, better understanding will come as well. |
@dajma00 Great! I was just making sure there wasn't something I was missing. The team is working through the very generic "auth is hard" feedback and are digging into specifics. When other frameworks come up we got looking for examples and I've yet to see something that was easy, but I want to make sure we're being kept honest (so keep sending the feedback). For teams/developers that don't know where to start or how to answer any of the relevant questions about authentication scheme, user management, supported clients etc., we need to have a stronger opinion here. We're going to spend a bunch of time building out samples to cover some "steel thread" scenarios based on the feedback we've received from several mediums. |
@davidfowl I consider ServiceStack auth to be easy to implement and well documented. Not sure if there are any parallels that help. |
It's not only people with no .NET experience that are struggling. A lot of us came spent the last 2 decades using Active Directory integration for everything, including SPAs. Now that we're moving to cloud-based deployments where AD isn't an option, the comparative difficulty level is coming as a shock. Which is why I'm advocating so hard for the samples to be directly offered in the VS templates. While better guidance at all would be beneficial, the ability to start a project with authentication from minute one is the goal. |
Some of the issues I've faced when starting a new SPA project:
I seem to have faced the following scenario in multiple new projects the last couple years. Say I'm starting my React SPA project with a simple username/password system using a built in IdentityServer (since that's what Microsoft currently recommends it seems). How do I login a React app? There's the MSAL javascript library, but that (by design) doesn't deal with the actual login process. For that we need to have an HTML form to let the user type in their credentials, then make an ajax call to our internal IdentityServer to validate. From there we need to somehow let the MSAL.js instance know that we are now logged in so that it can start keeping track of tokens, identities, etc. Once all of that is done we can then start making calls to APIs that require access tokens, and it's a simple matter of attaching the appropriate HTTP headers "Authorization: Bearer " for future ajax requests. Now for a developer that isn't an expert in OAuth, Microsoft Identity Platform, and IdentityServer, learning all of that at once is overwhelming. As far as I know, there doesn't appear to be an API for logging into an IdentityServer and initiating a session. I have no idea how to let MSAL.js know that login succeeded and it can now proceed with the OAuth protocol. A template that can provide all of that, would go a long way towards at least providing direction on what we need to tweak for our specific project needs. |
To add to feedback -- Just to be more specific, here is a simple requirement. May be I am missing something but it is not obvious. If I create a default Blazor wasm hosted project with auth individual accounts, and I want to give access to my APIs (not the wasm app) to third parties, what steps should be followed? |
@danroth27 New Templates is not suits for my needs and many other developers. The Old Template is very good related to Build and hides annoying npm install calls etc. during build. Helping deployments and pre compilation. Visual Studio was working okay with old SPA template. Following blog post promised that Microsoft will remove DuendeIdentity server from current SPA Templates and support those SPA Templates also in the future. But now SPA Templates are not included to SDK and cannot be used. Simple thing to just add again available those SPA Templates without DuendeIdentity server. https://devblogs.microsoft.com/dotnet/improvements-auth-identity-aspnetcore-8/ |
We plan to provide a mobile (MAUI) sample that will show token-based identity. The token solution is only intended for cases when you cannot use cookie authentication for some reason. Is there a case for Angular that prevents cookies from being used? |
Thank you for your response @JeremyLikness . While I appreciate the upcoming MAUI sample for token-based identity, I believe it's crucial to also have robust examples for SPAs like Angular. The core of my concern isn't just about choosing between cookie authentication and token-based approaches. Instead, it's about ensuring comprehensive security implementations on the client side, which is vital for the overall application security. Whether using cookie authentication or not, having the ability to refresh access tokens and implement multi-factor authentication is essential. These features are integral to modern web security practices and should be demonstrable in samples. By providing examples that cover these aspects, we can help developers more effectively utilize the full potential of the new Identity APIs. Moreover, including samples for functionalities like password reset, email confirmation, and others would be immensely beneficial. These are common features in many applications, and having clear, well-structured examples would greatly aid developers in implementing them securely and efficiently. In short, comprehensive samples covering a range of functionalities, including token refresh and multi-factor authentication, are vital. They play a significant role in guiding developers towards best practices in application security, regardless of the authentication method used. Best regards |
@kjartanvalur to clarify this
What does it mean to clarify the access token when using cookies? |
Hello @davidfowl Thank you for your question. You're correct in pointing out that in a cookie-based authentication scenario, the concept of refreshing a token isn't directly applicable as it is in token-based systems. In cookie-based auth, session management is handled server-side, and the cookie is more of a session reference than a bearer token. My initial request was indeed broader in scope, emphasizing the need for comprehensive samples covering various security features, including two-factor authentication, password reset, and email confirmation. These features are crucial regardless of the authentication method. However, considering the stateless nature of SPAs and their common use in Angular applications, demonstrating how to handle token-based authentication, particularly token refresh mechanics, would be immensely beneficial. It would provide Angular developers with practical guidance on implementing a secure, token-based authentication system that aligns with modern web application standards. I hope this clarifies my previous message, and I look forward to seeing such examples in the Identity API's documentation. |
I agree with you there. The community can help here as well. I think @JeremyLikness 's angular sample is a great starting point to build on. There seems to be lots of community interest and knowledge, and we can benefit from collaboration here (one of the benefits of OSS!). We're not going to build and maintain samples for every auth scenario and every framework.
We recommend cookies and a BFF as our default SPA story because there's no way to do this entirely securely in an untrusted client (depending on your standards). That said, I'm not against having a sample showing how to refresh tokens if you choose this approach for your SPA. Just know that the reason we avoid showing samples against our recommended guidance is so that we don't get the blame when they are copy and pasted without the caveats being considered. If you have chosen a deployment model or just decided that you don't want to use cookies, then you're in the territory of making security tradeoffs that may or may not be OK in your situation. Microsoft and the |
Thank you @davidfowl for your detailed response and for taking the time to address these concerns. Your insights are greatly appreciated and add valuable context to this discussion. I completely agree that leveraging open-source collaboration is a valuable way to explore and document diverse authentication scenarios across various frameworks. The community's contribution is indeed a significant asset in this regard. I understand and respect the stance of recommending cookies and a Backend for Frontend (BFF) pattern as the default for SPAs due to security considerations in untrusted client environments. This approach aligns with the principle of secure by design, which is crucial in today's web development landscape. However, as you mentioned, there are scenarios where developers might opt for different authentication methods due to specific deployment models or other considerations. In these cases, having access to comprehensive samples and best practices, including those for token refresh in SPAs, becomes invaluable. It enables developers to make informed decisions and understand the security trade-offs they are making. I appreciate the .NET team's commitment to providing information to help developers make the right choices. While Microsoft and the .NET team are not responsible for individual implementation decisions, the guidance and samples you provide are essential tools that help shape those decisions. In that spirit, a sample demonstrating token refresh for SPAs, accompanied by clear documentation of its use cases and limitations, would be a valuable addition. It would help developers who choose this path to implement it as securely as possible within the constraints of their chosen architecture. Thank you for considering this request and for your ongoing efforts in supporting the developer community. |
@davidfowl I would love to see a template with a BFF setup, whether it be for Blazor, angular, etc. |
@codemonkey85 Here's an Angular (nx V17) .NET 8 BFF using Microsoft Entra ID for identity. Maybe this would help you get started. https://github.com/damienbod/bff-aspnetcore-angular |
Long time reader of this issue... first time poster... It may be beneficial to ensure that we all understand what a design would need to be for an SPA to securely store and use a token from within a web browser. This design decision can be useful in a scenario where we have an SPA and we don't want to cache any Session State on the backend that is to be shared across multiple Web servers. In this case, the security between the browser and Web Application back-end can be implemented in a stateless manner with JSON Web Tokens (JWT). The following OWASP guidelines tell us how to transmit and store a token on the client-side as securely as possible. TLDR: The solution (which mitigates XSS and gives our backend confidence that an API request came from our SPA) requires a two-pronged approach - returning both a token to the API caller in the response, and also a hardened HTTP-only cookie with a fingerprint. I don't want to spruik my things, but I did a little rewrite summary of the approach which helped me to grok it better : https://devzone.channeladam.com/notebooks/web-development/javascript-web-apps-jwt-security/. Unfortunately I cannot contribute my implementation of this for commercial reasons - but this is how it can be done. I hope this information positively contributes to this discussion. |
@JeremyLikness Current discussion going to wrong direction. I just request that ASP.NET Core SPA Templates must be publish again and visible in visual studio 2022 add new project window with change where "Duende IdentityServer" dependency is removed and that's it. There is lot of opinions edge to edge what is best practice or not but simple single project template suits the best many business cases and simplify deployments a lot. I do not want to spend a lot of time to do extra work if forced to implement things hard way. |
I think people read bout typical cookie auth implementations and assume that ASP.NET Core is implemented the same way. The cookie format is also stateless (it doesn’t require session storage or stickiness), but it does use symmetric keys which need to be shared across servers. Is your JWT implementation using symmetric or asymmetric keys? There are valid reasons to use tokens for sure but I’m not sure this is one of them. @damienbod maybe we can use your samples to bootstrap this effort! |
This issue started tracking ways to improve templates with better authentication strategies/options for developers. Stick with old templates does not fulfill the objective of this issue. It seems it just fulfills your specific needs. So the discussion is not "going to the wrong direction", in my point of view. Wouldn't be easier, if you need to stick with the old structure, that you create your project using the old template and just copy specific code to the new template or update the old project to use .NET 8? Why new versions should support old technologies that have better (and, in this case, more secure) replacement options? |
oh that's good to know, thank you. Mine is symmetric too - each web server automatically pulls it from Key Vault via app settings config. |
Wouldn't be easier if Visual Studio even provides that old SPA Template but now it is fully removed. So it is impossible now to do that "create your project using the old template and just copy specific code to the new template" to get to know what changes removing "Duende IdentityServer" dependency means. |
You have the option to install an older version, then keep a copy of the template's structure in a project of yourself to serve as base for new projects, if the old structure matter this much to you. My point is: what you propose, to the limit, would've made Visual Studio 2022 had templates from the very first version only "because someone wants", without considering improvements made to the stack, using feedback of hundreds of people. I was a stubborn person in the past too and maybe even had thoughts similar to yours (because we, humans, don't handle well with changes), but the new product versions have a purpose behind the changes. For instance, if .NET 8 have a new type of project specific for the web, considering the new stack technologies, there is a point to start using it instead of the older MSBuild template (because of a better ecosystem, debugging, maturity, security, etc). What I see about some changes is that Visual Studio older templates are very opinionated on its structure, because of the way the stack was seen with proprietary technologies in Microsoft. This is not true for all stacks, because, in general, web stacks are "shared" between a lot of other stacks (PHP, Python, Ruby, etc), and seems (to me) that making things more independent would help even new developers to access the .NET ecosystem. I have no deeply knowledge of why the new structure exists, but I can see this movement between older and new structures, which makes sense to me at least. You always have the possibility to stick with older versions until you can manage to update or until the new stack has the maturity needed. This is indeed a possibility, because not every improvement (in the history of .NET) had come with 100% of the features the last version was (this is something that happens not so unfrequently, like in the transition between .NET Framework to .NET Core, EF -> EF Core, and so on...). It is great that you can give your opinion to improve the technology, and I hope it helps the team to fill any gaps that this new type of web project have. Until it happens, the best discussion I see is to discover what exactly are the problems/gaps in the new version that aren't fulfilled by the new templates. Concrete examples would be more helpful than saying that "you and other developers want it". References that may help you:
Some personal guidance that may help you (or someone else) to "migrate": old SPA templates had API and static code tightly coupled, which is something that is not so trivial in SPA projects - where the most common scenario (that I see) is that you would have an API (written as a WebAPI project in .NET, for instance) and a separate project for the static part of your client's code (Angular, React, Vue, etc), which would be your SPA project in fact. Then, you keep things separated, mainly because you could serve the static code in an edge server, for instance, and your API/BFF as a dynamic application, in any server. This way you have independent scalability, maintainability, etc... so it is a more logical way of thinking the project responsabilities. And maybe this is something that was considered in this movement between .NET 7 and .NET 8 (just a guess, as I already stated). Anyway... hope you find a better way to work (perhaps without needing to stick with the old stack). Best regards. |
If you install latest .net SDK and latest Visual Studio 2022 updates you must be able to use SPA Template projects for .net 6, 7, 8 -> But now it is not possible and promised updated version of SPA Templates without "Duende IdentityServer" dependency for .net 8 is not there available to use with any .net 6-8 versions (single project SPA template what will suits the best for our needs). https://devblogs.microsoft.com/dotnet/improvements-auth-identity-aspnetcore-8/ You cannot install side by side multiple Visual Studio 2022 instances but that is not at all relevant case. |
So the thing is that the new SPA templates are missing (not the old ones), right? As I see in docs, the new SPA templates should be available right in Visual Studio 2022, like stated here. |
I mean SPA templates what was promised to improve to .net 8 where "Duende IdentityServer" dependency is removed and still it is single project template ( https://devblogs.microsoft.com/dotnet/improvements-auth-identity-aspnetcore-8/ ). Should be possible to start a new project using that updated SPA project template using .net 6 to 8 versions where "Duende IdentityServer" is not there with cookie auth etc.. Following git commits are not part of latest SDK |
@JeremyLikness @damienbod @davidfowl |
I know this might be offtopic in this issue but still, I would be grateful if you could give me guidance about where I should look for advice. My use case: I have a web app representing a repository (resources to secure and stores user data) and a separate token auth server, using IdentityServer 4 (the previous, opensource version of Duende). This setup supports OAuth2 (and OIDC). My question is: if I wanted to do the same, which template should I use in .Net 8 and how would I implement this without having to license Duende? It would be nice to have a similarly easy-to-use, open-source solution for an OAuth2 auth server as before. Not sure if the new identity API in .Net 8 would help me as that is not a JWT-compatible solution. I would like to have an auth server that supports SSO (single-sign-on) whithout having to deal with OAuth2 implementation, I only want to customize the user store and the login UI. This is what IdentityServer let me do before, out of the box. I know of OpenIdDict but that is a lot more complicated than IS4 was. |
I found this post pretty insightful https://www.reddit.com/r/dotnet/comments/17qnvyv/choosing_an_identity_provider_authentication/ There's no, out-of-the-box template for an OIDC server outside of Entra, but each of those providers has docs on how to get started with ASP.NET Core. |
I'll just mention, if you only have one web app, I don't see any reason to have a separate OIDC auth server |
Thank you, that is absolutely true. However in our case the goal is to support multiple clients, including other asp.net apps, spas, even mobile apps - with single sign on. |
Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue. This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue! |
Well…I’m not sure exactly the scope of this issue anymore after the hundreds of comments(!), but I assume it should be closed by a human or broken into smaller issue instead of as stale by you @msftbot! |
Hi, we're looking at this and will clarify what issues/PRs are related and update accordingly. |
@JeremyLikness Any chance that there have been some new issues or PRs related to this in the last few months? I'm very interested in this topic and would like to follow up on any further advancements. Thank you! |
Is there an existing issue for this?
Is your feature request related to a problem? Please describe the problem.
I am trying to create basic SPA applications that manage their own passwords without the cost and complexity of third-party products like Identity Server.
Other's I'm talking to just want simple social media authentication.
We're all at a loss as to how to achieve this because none of the SPA templates give us any direction on how to proceed. There are out-of-band tutorials we can look at. But they are often incomplete or confusing, which is not acceptable for something that has to be perfect on day one. The phrase, "I'm learning authentication by trial-and-error" is quite frightening.
Describe the solution you'd like
The SPA templates for Angular, React, Blazor, etc. should include options for...
Additional context
We are regularly seeing posts on Reddit with titles like "Why is authentication such a XXXX show with .NET 6?" and "Does anyone else feel as lost as I do in the .NET Identity documentation?". The community is having a really hard time with this and needs far better guidance than what we're getting.
The text was updated successfully, but these errors were encountered: