Asp .net core - Authorize access to all files in a folder via roles - asp.net-core

I'm upgrading some initial razor code into asp .net razor pages with .net core 5.0. I've been through many examples on the microsoft site, but it seems that I have to set attributes in all of my .cshtml.cs files. that feels just sloppy and error prone because something will be forgotten somewhere.
In .net 4.x razor, I have an _PageStart.cshtml file, I check the user's role, and I redirect them to the login page if they are not in a particular role. I'd like to do the same in asp .net core using a single file or configuration. I don't want to put an attribute on every pagemodel file, that just seems sloppy. I imagine that I would do something like:
options.Conventions.AuthorizeFolder("/Club", "ClubAdmin");
where ClubAdmin is a role in the application and Club is a folder that contains a bunch of razor pages and sub folders. Is this possible?
TIA

To do this, you can define a policy in your Startup.cs file that checks for a role and then configure razor pages to Authorize that folder for that specific policy:
//define the admin policy
services.AddAuthorization(options =>
{
options.AddPolicy("AdminPolicy", policy => policy.RequireRole("Administrator"));
});
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/Admin", "AdminPolicy");
});
The RequireRole extension method injects a RolesAuthorizationRequirement handler that will validate for the given role during authorization

Related

Asp.Net Core Web Api hide controllers and actions by api-key authorization

I am converting an Asp.Net Web Api project to Asp.Net Core with .net6.
This project uses a custom Api-Key authentication and authorization method to give access to some of the controllers and actions.
In the old project, when opening the swagger documentation, the only controllers and actions displayed are the ones that do not require authentication.
Once the user inserts the api key and clicks on Explore button, the authorized controllers and actions shows up in documentation.
To do this, in the legacy project, I used IOperationFilter and IDocumentFilter to hide controllers and actions if not authorized.
This is working because when you click on Explore button after providing the api key, the page is refreshed and, at every refresh of the page, the IOperationFilter and IDocumentFilter are applied.
In Asp.Net Core, it seems that the IOperationFilter and IDocumentFilter are applied only at startup, and, in addition, the new Authorize button does not reload the page, and works only client side to provide authorization to the subsequent user interactions with the Try it out button present on every action.
Is it possibile to do something similar in Asp.Net Core, or should I drop that feature in the new version?
I found something may help you :
In asp.net core Swagger construct the UI page with a json file as below :
app.UseSwaggerUI(c=>
{                    
c.SwaggerEndpoint("/swagger/v1/swagger.json","SwaggerFilterv1"); 
});
This json file is constructed with the options you configured when you registed the service
Then I tried to copy the content of json file to the static file in the project ,deleted part of the path(you could also apply the filters and copy the json file directly ),and replaced the json file constructed by .net core
It worked as excepted : Some of the Api was missing
and you may inject your js file to control it(Add a request header you if auth succeeded and refresh the page and check request header with middleware):
app.UseSwaggerUI(c=>
{                    
......
c.InjectJavascript("")
});
I tried to branch the pipeline(I omitted the Authentication process just tried to check the query para):
app.UseWhen(x =>x.Request.Query.ContainsKey("Key"),
app =>app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/somejson.json", "SwaggerFilter v1");
}));
app.UseWhen(......)
The Result:

How can i add an API in an ASP.NET Core Web App

I have create an "ASP.NET Core Web App" Project in Visual Studio.
I want to add an API in this project ? I can create a separate Web API project but i want to put everything in the same project.
Is it possible ?
Thanks
If you want to keep the web app project and also add a few API endpoints you could just add a folder (e.g. Api) at the project root where you can place your api-controllers.
Then in that folder you can add a class that will derive from ControllerBase and decorate it with [ApiController] attribute and a [Route] attribute.
This requires configuration of controllers in your Startup.cs though:
In ConfigureServices() add a call to services.AddControllers();
In Configure specify the MapControllers() option:
app.UseEndpoints(endpoints => {
// other code
endpoints.MapControllers();
});
I would suggest you build an API solution, and then a separate Core Web App solution.
Otherwise you could try starting with a 'Blank Solution' and adding different projects to it.

How to give "admin" role access to all pages in .net core web project?

I have a .net core/5 razor pages project.
I'm using Authorize tags and Policy requirements to restrict access to pages. I would like to ensure that Admin has access to all pages by default without needing to add that to every policy or on every page using Authorize(Roles = "Admin").
services.AddAuthorization(o =>
{
o.AddPolicy("AtLeastStore", policy => policy.Requirements.Add(new StoreOrGreaterRequirement()));
o.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
I'm using Authorize tags and Policy requirements to restrict access to
pages. I would like to ensure that Admin has access to all pages by
default without needing to add that to every policy or on every page
using Authorize(Roles = "Admin").
You could set the Razor Pages authorization conventions, put the admin related page in an admin folder, then, use the following AuthorizePage convention to add an AuthorizeFilter to the page at the specified path:
services.AddRazorPages(options =>
{
// specify an authorization policy for the admin folder.
options.Conventions.AuthorizeFolder("/admin", "AtLeast21");
//Besides, you can also use the AuthorizePage method to specify an authorization policy for the admin related pages.
//specify an authorization policy for the page.
//options.Conventions.AuthorizePage("/Contact", "AtLeast21");
});
More detail information, see AuthorizePage, AuthorizeFolder and Razor Pages authorization conventions in ASP.NET Core.

Change LoginPath without ASP.NET Core Identity

Use cookie authentication without ASP.NET Core Identity
The login file is located at Pages/Account/Login.cshtml.
I wish to change to Pages/Index, but I am not able to change the LoginPath after trying various methods that I found using Google.
Try it with adding the following snippet inside the ConfigureServices method. It has to be placed behind your call of AddAuthentication().
services.ConfigureApplicationCookie(cookie =>
{
cookie.LoginPath = "/Index";
});

Role based Access to Static Content in ASP.NET CORE

Is there any way I can give access to static content based on their role. In my application, the authentication is done through Azure Active AD and the contents should be accessed based on their role e.g. employee should access all employee pages and students should access student pages. This is how my solution explorer looks like.
Solution Explorer
I know this is duplicate of Secure requests to .html files in ASP.NET Core but I couldn't find any approach to implement the solution. I have made new folder intranet outside the wwwRoot to serve my static content but still need to know how can I authorize the user and and serve role based static files.
As the document said, you could store the static files outside of wwwroot and any directory accessible to the Static File Middleware (for example: MyStaticFiles folder, like this), then, you could serve them via an action method to which authorization is applied and return a FileResult object:
[Authorize(Roles = "User")]
public IActionResult BannerImage()
{
var filePath = Path.Combine(
_env.ContentRootPath, "MyStaticFiles", "images", "Image1.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Then, you could view image by click the following link:
<a asp-action="BannerImage" asp-controller="Home">View Image</a>
[Note] After using the above method, if the authorize not working, try to clear the cache, perhaps the issue is related to the browser cache. Besides, if you meet the "HTTP Error 404.15 - Not Found" error, try to add [AllowAnonymous] attribute for other controller action method.