Skip to content
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

Scaffolding into Blazor Server apps #17940

Merged
merged 11 commits into from
Jun 4, 2020
Merged

Conversation

guardrex
Copy link
Collaborator

@guardrex guardrex commented Apr 21, 2020

Fixes #15651
Fixes #13316

Internal Review Topic

  • For a RedirectToLogin component, note that ...

    • I had to use the force flag set to true to make it redirect to the Login Identity page. Otherwise, it won't redirect to the page.
    • It breaks the browser's Back button, but it works.
    @inject NavigationManager Navigation
    @code {
        protected override void OnInitialized()
        {
            Navigation.NavigateTo("Identity/Account/Login?returnUrl=" +
                Navigation.ToBaseRelativePath(Navigation.Uri), true);
        }
    }
  • You have to POST to the Identity logout endpoint (Identity/Account/Logout) from the component (or to a dev-created endpoint per Javier instructions here). To POST from an HTML form, the app requires an XSRF token. This PR covers the scenario using Javier's Pass a token to a Blazor Server app approach. Check for a 💩 Rex Code Smell!™️ 💩 there, but it seems to work well.

  • Styling in Pages/Shared/Layout.cshtml for Identity pages to use the Blazor theme works ok, except that secure components should be removed from the NavMenu component for the page layout. I have the reader create a new NavMenu_IdentityPage component for their pages layout page. If you try to use a secured component in the NavMenu, the Navigation Manager redirect in RedirectToLogin hits a 💥. The guidance here is very preliminary (and I placed a NOTE in the guidance that says so), but it probably starts readers off in the right direction.

Updates

Updates

Updates

Update aspnetcore/includes/scaffold-identity/id-scaffold-dlg-auth.md

Co-Authored-By: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com>

Remove dup Identity code in Startup

Use the relative path for Login redirect

Login redirect requires the force flag

Surface a Identity pages styling approach
@bdnts

This comment has been minimized.

@guardrex

This comment has been minimized.

@guardrex guardrex requested review from a team and removed request for danroth27 and mkArtakMSFT May 5, 2020 00:38
@guardrex
Copy link
Collaborator Author

@mkArtakMSFT @danroth27 It's been a month on this one, and we don't have any guidance at the moment. Do we need to hold off on this further? Check my opening remarks ☝️ for the contentious points.

@bdnts
Copy link

bdnts commented May 22, 2020

Hi @guardrex I've managed to do a Blazor Server app with 100% Blazor pages for A&A, and no calls to Razor pages, or kludges on the use of XSRF, or writing APIs. And it is gorgeous! I found notes from @SteveSandersonMS about ServerAuthenticationStateProvider, (SASP) and others about how to use RevalidatingServerAuthenticationStateProvider (RSASP) for host/local authentication, bypassing SignInManager. (yes, I bypassed it signing in, no "rendering in progress errors" and HttpContext is null.) Further experimenting, I found that when creating a blank Blazor Server app, with Identity, it generates RSASP by default. SASP inherits from IHostEnvironmentAuthenticationStateProvider (IHEASP), and 🎆 it works! AuthentitcationStateTask and <AuthorizeView> and everything else in MS Identity work as documented. For ootb dev work, it is great. I've pushed my project to Azure, and everything works as advertised. No dependency on HttpContext.

The downside is that refresh/change the underlying websocket, and authentication is lost (it is a new circuit, so of course it disappears). I haven't gone any further on this issue, but I haven't needed to either for the scope of my dev work. When I start moving to Production, I'll switch out to AD B2C anyway, so I'm not losing anything over this issue. (FYI, not using AD B2C up front because of the UI/UX downgrade from Blazor. Secondly, my SUSI flow is different from B2C default. Together those equal massive customization, which is not my priority.)

Frankly with the release of WASM, I'm not sure 100% Blazor Server app is even relevant any more? Maybe Education as a use case, but any serious application will probably be Server and WASM, and we already know API and Token based A&A works with BS and WASM combination. So what problem are we solving?

I've been crunched with deadlines (haven't we all been this month.) so I haven't built a repo of my solution yet. If this is important, I'm happy to do so and share. And now that A&A are working, I've caught up on my work, just a bit. Just let me know how I can be of assistance.

@guardrex
Copy link
Collaborator Author

Thanks for that @bdnts and congrats 🎉 on working it out.

I haven't built a repo of my solution yet. If this is important

That would be helpful if I find out from engineering that that's what they want done. In that case, I can take this PR in that direction. We should co-author the updates based on your work if that's what they want.

At this point, the PR follows the direction of the templates. The components interact with the Identity via normal Identity endpoints. It's a low-hanging fruit approach that doesn't require much code or thought.

Anywho ... we'll see what they say and then take it from there.

I'm not sure 100% Blazor Server app is even relevant any more?

You might want to get out of there! ... There's a 💀 Microsoft Hit Squad 💀 in-route to your location. ETA 10 minutes! 😄 lol ....... ⚰️ Here lies @bdnts - Gone but not forgotten - RIP ⚰️ 😁 lol

Seriously tho ...

So what problem are we solving?

The same reasons for Blazor Server persist. They're listed in the Hosting Models topic at ...

https://docs.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-3.1#blazor-server

@bdnts
Copy link

bdnts commented May 22, 2020

😆 Hah, What are they going to do? Hurl insults and then apologize because they hurt my feelings? 🤣 I'm tougher than that. 💪

Actually, I see that when creating a WASM with Identity, there is no Work/School Account or Windows Authentication option (greyed out). So I guess there is a use case for BS using Work/Windows AD internally at a business. Good to know. I withdraw my question. ("Knock. Knock" "Who's there?" "WHACK!" Wife took em out. 😄 )

I'll go ahead an knock out a repo, as my day keeps getting interrupted, and my next task needs about 10 hours of non-interruptions (I did 36 hours non-stop coding yesterday to release 2 major features. 😪 🛌 😴 ). This will take about 4 hours, and it is Friday. (I work for myself 🤳) Time to goof off. 🤪

Let me know what Engineering says and will go from there.

@bdnts
Copy link

bdnts commented May 27, 2020

Hello @guardrex. Well, I believe I have a solution to Blazor Server Identity that matches the UI/UX experience of MVC/Razor when creating a new application. Both in terms of time and functionality.
See https://github.com/bdnts/BlazorServerIdentityInterop for full details.

The short answer is MVC/Razor pages are approved/guidance for Blazor Identity, but the issues with this approach are well discussed (UI/UX). I experimented with the solution of storing the AF token in _Host.cshtml file, but as some people remarked, it was "kludgy." So I took a new approach:

  • Create a new project with Identity activated, but not scaffolded.
  • Modify Startup.cs to add the AF token as a header, not part of the DOM.
  • Create a custom SignIn.razor
    • Collects credentials in a Blazor form.
    • OnValidSubmit() after checking validity of credentials
      • Make Http call to Login.OnGet() and get the form, with the AF token attached.
      • Build new request with Credentials + AF token in the Form data + AF token in the header.
      • Post the request to Login.OnPostAsync() User credentials are validated.
      • Response (if successful) contains Authentication Cookie.
      • Use Oqtane's Interop.SetCookie to add it to the Document.
      • Magic coming Use NavigationManager.NavigateTo("/", true) to load the browser with authentication cookie.
        • The true setting If true, bypasses client-side routing and forces the browser to load the new page from the server, whether or not the URI would normally be handled by the client-side router.
        • Voila, the authentication cookie is loaded into the browser, and all A&A facilities work as documented, and the UI/UX is just like Asp.Net Core, but 100% Blazor!
  • There is the interop.js and wrapper interop.cs that I borrow from Oqtane.
  • Then come the the SUSO components.
  • There is some modifications to LoginDisplay.razor to show the SUSISO components.
  • That's about it.

This is clean, simple, and robust. And it is not kludgy 😆 I've published it to Azure as BlazorServerIdentityInterop.Azurewebsites.net for review, and the source is at https://github.com/bdnts/BlazorServerIdentityInterop.

How I figured this all out, and why I'm confident in it, is I put a protocol analyzer on the wire (Fiddler), and watched the traffic of how Login Razor page worked, and then replicated in Blazor SignIn page. Because I'm working with unscaffolded Identity, I can't change anything in the Login.cshtml.cs, because I don't have the source version. This insured the solution would be compliant, especially in XSRF.

In the Readme.md, I have laid out the various use cases, technical and non-technical constraints, and the various implementations available, upsides and downsides. With the constraints the way they are (and I do cite documentation to make the boundaries clear), I think this is a great, low-end solution.

Cheers

Copy link
Member

@mkArtakMSFT mkArtakMSFT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine to me. If I miss something, we'll learn about it soon.

@guardrex
Copy link
Collaborator Author

guardrex commented Jun 4, 2020

Thanks @mkArtakMSFT ...

Yes ... the community will sharpen their BEAKS and CLAWS 🦅 for me if they see something off.

I plan to revisit this on UE passes shortly, too. I'll walk the steps again at that time and see if it still holds up or what it further needs.

Thanks again @bdnts for discussion and help on this.

@guardrex guardrex merged commit bb378a3 into master Jun 4, 2020
@guardrex guardrex deleted the guardrex/blazor-scaffolding branch June 4, 2020 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add two sections with details about scaffolding into server-side blazor apps Logout Flow
3 participants