Should I check the authorization of a user inside every view? - c#

So I'm working on a MVC project in .NET Core 2.1.
I use the built in Cookie authentication from ASP.NET Identity.
All my endpoints inside my controller that would require authorization are annotated with [Authorize] of course. But, do my views (that get returned) also need a form of annotation to define they are only accessible for users that are authorized? If that is the case how would you do that?

Checking the authentication or autorization in a .cshtml-View contradicts the MVC-concept in my opinion. When the request hits the "View"-part of MVC there was already a corresponding controller involved which did its job and called the view engine. At this Point you are (or should be) done with handling business logic - and permissions are just another form of business requirement - and present its result the most fabulous way.
So to answer your question concretely:
But, do my views (that get returned) also need a form of annotation to define they are only accessible for users that are authorized?
Since they are only accessible through controllers (or should be), they don't need additional annotations.

Views or partial views can only be accessed by any action of controller so if you apply [Authorize] filter on controller or action then no need to use that in view.
But if want to authenticate the user in view then You can use Identity User's extention method IsInRole("Role").

Related

ASP.NET Core MVC/WebAPI Authentication Schemes plus Anonymous

I'm having an issue with a website plus API I'm writing. These are in the same project, if that matters.
Reduced to its simplest form, it's a catalogue website and API. You have products in a database and pages which display product information. You also have other pages which allow editing this information and adding new products, etc.
There are three ways you can do this:
Anonymous users can list products and view public information about them on the website.
Signed-in users can list, view (including private info), edit, create and delete products on the website.
Users with a valid API key can list, view (including private info), edit, create and delete products using the API.
The problem I'm having is that the website uses AJAX calls to the API, and these only work if the user of the website is authenticated. Calling the API without an authentication cookie or an API key fails by design.
What would be the recommended way of identifying the unauthenticated website to the back-end API in a secure way that allows it to work?
The ideas I've had include:
A special API key for the website, but it would by necessity be visible to the world at large somewhere in the Javascript code and therefore something someone could use to access the API themselves and bypass any rate limiting I wanted to implement.
I considered setting something in the session on the web controllers which could then be verified in the API controllers, but I encountered issues where unauthenticated calls to the API redirect to the login page on the Account controller, which then sets the relevant session variable, which means subsequent API calls succeed whether legitimately authenticated or not. This seems like the most promising option, but I'm not familiar enough with ASP.NET Core's workings to make it robust.
You should use Jason Web Token Authentication, to implement one in your API please check the following the link:
https://medium.com/#adegokesimi/implementing-jwt-and-refresh-token-in-net-core-2-2-web-api-b21ef6de2a19
By using JWT authentication in the pipe line of your WebApi your problem will be solved.
Also, you can use a ASP.NET Core identity system for things like roles that can be implemented on specific controller methods, for example, "EDIT" can be allowed only to role admin, etc.
Kind regards,
.js

Hard-coded domain controller MVC

I've been tasked with checking if the domain controller for a C# MVC web portal has been hard-coded, and if it has, update it. I have access to the source but I can't seem to locate where the domain controller is defined.
I'm wondering where the domain controller is usually set up in an MVC project (in a config file or within a controller class) or at least what the code would look like.
Any advice would be helpful.
It depends. How would a domain controller be used? Is the site using Windows authentication? Is it accessing Active Directory for some other purpose?
Regardless, the easiest way would likely be to get a list of all your domain controllers (if you have one domain, there likely isn't that many) and do a solution-wide search for each.

Cookie authentication for MVC and OAuth for WebAPI in the same app

I have an asp.net application that has both MVC controllers and WebAPI controllers.
For cookie authentication I use app.UseCookieAuthentication(... middleware with DefaultAuthenticationTypes.ApplicationCookie authentication type.
For OAuth I use app.UseOAuthBearerTokens(... middleware.
For MVC routes I have used AuthorizeAttribute as global to prevent anonymous access. Interesting thing is I can get data from MVC controllers too having access token recieved through oauth.
I understand that oauth middleware sets current user while processing request with token. Now I added additional attribute for MVC part to reject users with authentication type != DefaultAuthenticationTypes.ApplicationCookie.
Now requests with tokens will work only for WebAPI. Is this a good approach or am I doing something wrong?
Is this a good approach?
Not really, its not the authentication mechanism you want to prevent, you are likely to want to restrict access to just your MVC front end, the razor templates. You could use a custom filter similar to how it is explained in this response to ASP.NET MVC preventing users from direct URL except your filter should check that Request.Url.Host is in your list of known endpoints.
using System;
using System.Web.Mvc;
using System.Web.Routing;
namespace Customer.Filters
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class PreventFromUrl : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// MVC requests will originate from the same host as the server
// external apps may not have a referrer or it will be from a different domain
// If you have your own non-mvc code, in the same domain, we trust you know what you're doing :)
if (filterContext.HttpContext.Request.UrlReferrer == null
|| filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
{
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
}
}
}
}
If a Filter does not work, consider moving your Web API to a separate project, but be aware that this is really just a security by obscurity measure, it is still possible to use cookie based authentication to obtain access to your MVC endpoints once the caller has authenticated.
Using the authentication type alone does not provide any additional security benefits, you are just saying that each route requires specific way to authenticate, you are not doing anything to deny access itself.
You are expecting all non-MVC traffic to use OAuth, but because your site supports cookies, external apps could still programmatically and legitimately use cookie based authentication and gain access to your MVC controller endpoints.
is it important to deny access to your MVC controllers?
Your application logic should always be written with security in mind, your server-side controllers should not rely on the front end to validate and sanitise user inputs, any business rules and validation expressed in the user interface should also be evaluated in the controller logic.
Perform and design validation and business rules in the back-end first, in your controllers.
Because front end scripts are executed on the client they are therefor in a much more vulnerable state. It is trivial to capture and monitor the traffic that the front end sends back to the client, there for it you can work around client-side validations by manipulating the data before sending it back to the server.
Or worse, evolving client technologies might create scenarios where your client-side scripts and logic do not evaluate the way you originally expected, accidentally allowing un-sanitised or invalid data to flow through.
When the controller performs all business rule validation, as we are conditioned to do in Web API, then in general it should not really matter if the end client is your expected MVC client or something custom written. Even if someone wrote an app to automate or impersonate a valid user, If the caller has legitimately authenticated, let them in, because they could otherwise login directly through the MVC site manually or through the API.
It is pretty easy in MVC apps to put validation in the user interface level and to skip performing the same checks in the server-side, in this scenario, or when your MVC app exposes more data than you want to allow external clients to access it can become important to deny access to these MVC routes for non-mvc callers.
In general, supporting multiple authentication mechanisms is a good approach for an API because it broadens the options that clients can use to interact with the API. So supporting multiple types of auth to access the WebAPI routes IS a good approach.
This scenario makes it easy for your front end to access data through both the MVC controllers and the WebAPI. A common scenario that I encounter is when we use the API to secure access to external files and images. we can put the URL for the resource endpoint directly into and use the auth cookie that is already in the user's browser to access through the API.
Supporting Mutliple Authentication Mechanisms or Providers will increase the attack surface of your API. This not necessarily a bad thing, but it is something to be aware of and to audit.
Increased attack surface does not automatically mean that the service is more vulnerable, but it does mean that there are more points of potential failure in your authentication.

ASP.NET web method custom page based authentication

The current project my team is working on uses webforms asp.net and are unable to at this point in development move to MVC or WebAPI.
We have started to use a WebAPI style approach using javascript client side functionality for most the page work and using webmethods for CRUD style functionality.
The issue I am having is finding a simple clean method for checking authorisation of these webmethods being called. We currently use a custom made role based security that stores a list of pages that a role has access to and on page pre init checks if the users role has access to the page and if not redirects.
My ideal solution would be to use a custom attribute like WebAPI's authorize that I could create that checks the authorisation and if fails, throws an exception and never enters the webmethod.
Is this possible, and if so how is the best way to approach?
If not has anyone else come across a similar situation that they resolved cleanly. The last thing I would like is having to add extra parameters into a webmethod just to check the authorisation.

How would you architect visitor and admin functions in a single ASP.Net MVC web application?

So I have been working on a small web application (site) for a group of friends of mine and have come to the realization that things need to change. The application has two faces to it
a public facing side that serves dynamic data to visitors and non admins, and
an admin side where admins can update or create the dynamic data to be served.
This application started off as a single webforms project sectioned off by separate pages and and web.config security of folders. Then it grew into separate projects (MVC admin side and webforms front end). I later had to bring it to where it is today, a single web app with a mix of MVC (admin) and webforms (public), due to deployment issues.
Now I am looking at migrating it to a single MVC project. I would like to keep my administration functions desperate from my public facing side by URL like /Admin and am not sure how to do it. I have read a lot of topics on grouping controllers into modules but am not sure that is the right thing yet.
Should I just create admin functions inline with the rest of the public app and determine if the user is logged in or not?
Or should I create Admin controllers that are separate from the public controllers (EventAdminController vs CalendarController)?
What have others done?
Suggestions welcome, thanks stackoverflow.
Yes I am using the ASP.Net MVC framework from Microsoft. Darryl, are you saying to place my views in an Admin folder and protect that it using a web.config (to check security and roles) or to place my controllers in an Admin folder?
My assumptions was that you were saying to place the controllers in an Admin folder, say under controllers. This would still mean that HomeController in /Controllers is different than HomeAdminController in /Controllers/Admin. In this case you could configure specific routes for each but I don't see how simply putting a controller in a different folder would protect them (unless using the Authorize attribute on actions).
As for placing the views in a different folder, I can see how that could work in theory. But wouldn't the controller (in theory without any authorize attributes) still execute up to the point that the view is returned? I would then either expect a redirect or an error. Either way I wouldn't want to execute my controller action if you can't get to the view, and would rather not do any internal action pre-checking.
We have a similar problem where we are creating a very large ASP.NET MVC application and to separate functionality into areas we are using a process very similar to this post by Phil Haack. By creating areas you can have unique controller names for each area instead for the whole application, you can separate your modules far more easily and you can share authentication and basic common functionality.
On a MVC project I am working on I put all the admin stuff in an admin folder. To see the admin folder you must be authenticated and in the correct role. My controllers tend to be very minimal, most logic is in a business layer that the controllers use.

Categories