.NET Core 3 Razor pages app - Authorize all pages within an Area - asp.net-core

I am trying to lock access to all the pages in selected Areas in my Razor Pages app. So far I have this sample structure
Areas
Account
Index.chtml
Business
Index.chtml
If I add
options.Conventions.AuthorizeFolder("/business", "/index");
to startup, it works on a per page basis, but I cant see any clear way to lock the entire Business folder.
I've tried the folder based options mentioned here
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/razor-pages-authorization?view=aspnetcore-3.0
but none seem to work. Is this even possible?

So 10 seconds after asking, this works
options.Conventions.AuthorizeAreaFolder("business", "/");

Related

Should I place a script partial on EVERY page, or in the Layout.cshtml partial file?

My organization is currently working on a new ASP.Net Core web app. We have a couple of common Javascript functions that are used on all pages. At first we put the scripts in a partial file and started adding the following to the Scripts section on every page.
#{await Html.RenderPartialAsync("_CompanyScriptsPartial"); }
At this point we have only added it to a small handful of pages, but have around or so left to add it to.
Is it better to add that on every single page, or can I just put the same code in the layout.cshtml (it works when I do it, I just don't know if I should do it)? What is the 'best practice' method for this scenario?
If the scripts are used on all of your pages, or even if they are used on most of the application pages, then it is better to add the script link to the layout.
This way you avoid duplicating code by not adding RenderPartialAsync to every page.
Best practice is not copy and paste code and to have a single location for common code.

ASP.NET Core 2.1 Remove Identity Pages created using Scaffolding

I'm probably just missing a simple trick here, but I created the Identity framework in an ASP.NET Core project, created my own fields with my own classes, ran migrations, then once confirmed it was all working with the Default UI. It was working perfectly so went to customize the Identity UI so I could better control specific pages. Trouble was, thought I'd be adventurous and select every page to customize... yes dumb I know.. Now I've got some 80 pages or something that I no longer want.
I really only want to scaffold the registration and manage data pages, if I ran the Scaffolding again will that simply create new pages or fail because the pages already exist, or will it remove any pages that I don't select? I'm loathed to try it for fear of breaking something.
Perhaps it's down to manually deleting the pages I don't want, but will that cause issues with those pages that I haven't selected to customize. Seems great there's a scaffolding option to create the pages, but removing them... it's not so obvious...
For removing unwanted Identity Pages, you could delete them directly from your solution.
For Identity Razor page, if you add scaffold pages or manually create the razor pages with the corresponding name in Identity/Pages/Account, they will replace default Identity Razor page implementation. If there is no razor pages or you delete them, it will reuse default razor page from Razor library.

VS 2017 ASP.NET Core Web Application and Individual User Accounts works but pages are non-existent

When I create a web project using "ASP.NET Core Web Application" / "Web Application" (non-MVC) / "Individual User Accounts"... I get the sample project with Register and Login buttons that show their respective pages when I click on them. HOWEVER... the very weird thing is if I search for "Create a new account" which is on the register page it's not found... and more... there is no AccountController in the Identity area or anywhere... so 1) the pages aren't anywhere in my solution folder and 2) how in the world are these pages showing up?!? I've tried on two different computers now. (using Core 2.1)
As an example this link works:
<a asp-area="Identity" asp-page="/Account/Login">Login</a>
and takes me to:
https://localhost:44300/Identity/Account/Login
and yet my folder structure (both in the solution and on disk) looks like this:
ASP.NET Core 2.1 with Identity automatically includes the "Default UI". It's a Razor Pages class library that's referenced via AddDefaultIdentity in Startup, which under the hood literally calls AddDefaultUI.
If you want the actual files in your project, you need to scaffold them in. Right click your project in the solution explorer and choose Add > New Scaffolded Item... Then, click the Identity listing on the left, and then the Add button. A new window will pop allowing you to select the pages you want included, your context, etc. Configure it how you like and go.
It's also worth noting, that as long as you use AddDefaultIdentity, the default UI is still included, which means you don't actually need all the scaffolded files if you want any of them. They'll essentially function as overrides. Anything specifically included in your project will be used, while anything that's missing will be pulled from the default UI.
This also means that if you want to do something like use standard controller actions and views instead of Razor Pages, the default UI will still be active, and take precedence. You have to use AddIdentity or AddIdentityCore instead of AddDefaultIdentity if you want the default UI off completely.
ASP.NET Core 2.1 introduced Razor UI in class libraries. Identity with it's UI is in nuget package.
The nice thing about this is you can now package UI with your libraries and then expose the UI for overriding.
This post describes how to override the UI. Essentially, you add the pages you want to override to your project to /Areas/Identity/Pages.... the easiest way currently is to run the scaffolder for identity and a visual walkthrough.

How do I switch the theme used on a Sitefinity based website?

We have a Sitefinity 3.2 site in production and the users want a whole new look and feel. Upgrading is not an option.
I have created new templates for them but they will need to go into the site and create all new pages using the new templates. This is a problem because they want the current site to remain unchanged until they are done - then they want to instantly switch over.
One problem that I see already is that pages will not show up in the menu control until they are published.
I am very new to Sitefinity. Is there a standard practice for doing this?
You don't need to re-create all of the pages to change the look and feel; simply change the template assigned.
This video shows how to work with themes and templates.
I'd think that changing the theme of all the templates late at night should be "instantly" enough for most people. :)

Need to access the Page object in Global.asax in the PreRequestHandlerExecute

I have a huge website (containing around 5000+) pages. There is a theme functionality in the website where user can choose different colors for their profile. Now i want to use the ASP.net theme feature and put different CSS (for different colors) in the theme folder and in Global.asax i want check the user theme and render appropriate link element with the css. But my problem is, i am not able to access the Page element for adding the link in the page.
Here is my code
Dim page As System.Web.UI.Page = TryCast(System.Web.HttpContext.Current.Handler,System.Web.UI.Page)
page.StyleSheetTheme = "Black"
But when i run this code I get a Null reference error.
P.s : My application is very huge so its not possible to have a master page or a base class and inherit it in every page.
Please suggest.
The page is not available in PreRequestExecute. This function is called before asp.net steps in to handle things, and asp.net is responsible for the page. Think of PreRequestExecute as being earlier in the scheme of things, like when IIS is first trying to figure out what to do with this thing it has, the thing is not even a page yet.
You might want to look into some of the other events that you can hook, there are events that would take place after the page has loaded that may allow you to do what you are suggesting.
Rather than going into global.asax for this, consider using master pages. One possibility is to have nested master pages, where the first master page sets up overall layout, and the nested master handles the theme. (Or one of several nested master pages, all referencing the same top-level master page). If necessary, you can use the PreInit event in the page to change master pages, and select the master that matches your theme selection.
You can centralize this function by having your own class that inherits System.Web.UI.Page, and have all your own pages inherit this new class. Handle the PreInit event there. (As well as other useful functions, like page-level handling of unhandled exceptions, general security issues, etc.
EDITED TO ADD: As #aepheus correctly notes, the page hasn't been instantiated at the PreRequestHandlerExecute event. So there's no page class you can access.