Custom User and Roles with ASP.NET MVC3 - c#

I have a ASP.NET MVC site with a CAS server set up as the authentication type. I also have a separate database with a Users table and a Roles table (with a User being related to one or more roles). A User is only able to log into the system if the Username is both in the User table and on the CAS system. I have this solution working.
My problem is i now need some form of trigger on User.IsAuthenticated so i can track the current User (from my database), without the possibility that i am trying to allow tracking of a User that has logged out. What I've been thinking is i need to add the User to the HttpContext but i am not sure how to trigger the clearing of the User if the CAS session times out or if the User Logs out.
I also wish to have some functionality such as User.IsInRole (again using my database, not ASP.NET) but am not sure how to go about implementing this. I suppose if i can successfully add the User to the HttpContext then a IsInRole method would simply be a User.Roles.Contains(string role) method but how can that then be used if i wish, for example, to use a method with the DataAnnotation [Authorize(role = "ExampleRole")].
I have looked at questions such as How do I create a custom membership provider for ASP.NET MVC 2? but this doesn't work for me (possibly to do with me using the CAS authentication?)
Any guidance or background reading would be appreciated as i'm really not sure where i should even start. I have read up on GenericPrinciple, IPrinciple and IIdentity but I'm struggling to see how i can apply them to my current project.

Ended up with a custom Authorise Attribute that uses the CAS logon to check the user exists in my database. It also checks the roles of that user. I also used a static class to save the current user in the session with a logout method that abandons the session when the user logs out.

I have kind of a two parter for you. This link does a really good job of explaining how to replace the HttpContext User with your own object: http://bradygaster.com/custom-authentication-with-mvc-3.0
His approach uses MVC filters, but you can also catch the Authentication event in the Global.asax file. Using the forms system with your own implementation can be trivial or not depending on what you're doing, but it boils down to calling FormsAuthentication.SetAuthCookie and .SignOut, amidst your own logic.
public static void FormsLogin(this User user, bool persist)
{
FormsAuthentication.SetAuthCookie(user.DisplayName, persist);
user.AddHistory("Login event.", HistoryType.Login, "SYSTEM");
Users.OnUserLogin(user);
SetLastActivity(user);
}
public static void FormsLogout(this User user)
{
FormsAuthentication.SignOut();
}
Lastly, once you've got the login stuff working out, you can use your own more complex permission system by making a custom Auth Attribute. I remember piecing this together from some other answers and articles but I can't seem to find the sources at the moment, I will try and edit with sources for credit where it's due, if I find them. For now, all I can offer is this gist which offers up one of the attributes I use: https://gist.github.com/1959509
Keep in mind the only really relevant part there is the override of OnAuthorization, which does the actual work.

Related

RESTful API Design - same path diffrent roles

I´m currently working on a RESTful API, which has to give access to two diffrent Roles: Admin and User. (I'm wokring with Azure AD App Roles)
My Problem is that I don't understand how I can design the controller logic.
For example I want both (admin and user) to access the endpoint /books, but the admin is allowed to see all books and the user is only allowed to see his books.
What is the best practice to give both the allowed access? I thought of splitting it into two enpoints like this:
/books -> with annotation [Authorize(Roles="Admin")]
/user/{id}/books -> with annotation [Authorize(Roles="User")]
Thanks for helping!
Best regards
I think this sample may be of some help. And if you need sample written by other languages, you can refer to this document to find a suitable one.
And on your case, I think the most important thing is to find out the way to execute the right query and make the query result return to correct user.
So if you set a specific url for each user(I don't think this a good idea to expose user id in the request link), or you hide the user role/id into the token which contained in request header, you all need to write logic code to check which query method need to run. For example, hit domain:port/books with an access token, then your filter catch this request and decode the token to know the user id and user role, and maybe can save them in the session, then your controller may check the value stored in session and choose a right query to get the books information.

C# .NET 4.5 activity-based authorization WebForms (not MVC)

Currently I’m trying to implement activity-based authorization in my webform application. In my application you have different roles: Admin, manager, employee, and trainee.
The application communicates with my database through my BLL (business logic layer) and what I’m trying to do, is have authorization on method level in the BLL for all the reader and manager files for all my entities, like so:
[Authorize(Activity = "CreateUser")]
public static void InsertUser( ... )
[Authorize(Activity = "UpdateEmployee")]
public static void UpdateEmployee( ... )
For every method I want a CRUD activity and in the database I want to tell which roles gets to do what activity, or something that´s a lookalike like this.
Role-based security is not an option, besides for logging in, because a trainee for example is not allowed to insert or delete any data, except for one entity. So I need a permission/activity based authorization in my webforms.
Currently all I can find are solutions for MVC and .NET Core, but not any for the webforms, or the posts are from 2011 ish which don't really offer a solution, and I wonder if anyone has any new ideas or solutions as of this time.
In my project I make use of FormsAuthentication, and in my webconfig file I autorize specific roles and paths for specific roles. But this won’t cut it. I also make use of the Application_OnPostAuthenticateRequest in the global file with the FormsIdentity with my custom principal class which makes use of the IIDentity and IPrincipal.
Also, my AddEdit pages are the same page, and based on the querystring passed in the URL, like a userId, or employeeId, the save button decides whether it's an insert or update. So this is the reason why I need auth on methods.
So my question, does anyone know a pattern that I can actually implement in asp.net 4.5 webforms that gets permission or activity based authorization without having to hardcode everything so it's more future proof?

Is it valid enough to use sessions to maintain logged in user data in MVC Application

I am working on ASP.net MVC web Application. Here, in this i am implementing windows authentication. I have made necessary configurations in the web.config file to make it work
By using windows authentication, i was able to get the logged in user name . By using it as parameter, i am querying database to get the role for logged in user.
In my application, i have two roles. Admin and Normal User. I need to display some of the pages content based on the role of user logged in.
Can i use sessions in MVC to carry this information in every page and display the content
For example: in Global.asax
protected void Session_Start(object sender, EventArgs e)
{
Query database....
if( role="Admin")
{
Session["UserType"]="Adimn";
}
else
{
Session["UserType"]="NormalUser";
}
}
like this.. Then in each page, i will check this role and based on that i will hide/show some of the functionalities to the user
Is this the right approach to do this. IF not, what are the alternative ways of doing it.
Please suggest..
You should use HttpContext.User.Identity to get current user. You can get user name and user roles:
var uName = HttpContext.User.Identity.Name;
var isAdmin = HttpContext.User.IsInRole("Admin");
As any caching approach it have positive and negative sides. Your call if you are ok with solution. Some pro/cons below.
Pros:
less requests to DB
faster pages (again you need to just load session state)
Cons:
cache invalidation is complex problem: i.e. you may not know if particular user is no longer admin
leaking session due to bugs in your site allows elevation of privileges (just need to have session ID, not need for admin credentials).

Simple Membership Admin Accout

I am working on my first ASP.Net MVC 4 application and now stuck with one simple use case.
I need to authenticate one single user (Admin) so that he/she can log in to admin area to perform certain tasks. Though the ASP.Net internet project template has Account controller using simple membership but that seems to have much more than what I actually need. For instance, I don't really need the user registration functionality and user roles. My requirements are fairly simple, just to store one single user in database, give him the options to update his info like password, email etc and grant him access to admin area (admin controller and actions).
What I can't figure out is
Are simple membership or other asp.net membership provider my only options for this simple scenario.
If not what other option do I have in order to use [Authorize] to secure admin actions
You can build a custom method to grab the user and their stored role, then evaluate it in your controller. So, for instance:
public ActionResult GetAdminPage()
{
var loggedInUserName = HttpContext.User.Identity.Name;
var user = somesortofproviderlookupmethod(loggedInUserName);
// Assume user is a bool and is true
if (user)
{
return view("AdminPage");
}
}
The only thing I'm not sure of is whether or not HttpContext.User requires membership. Perhaps someone can shed some light. If so, perhaps you could send the username from the view, but then of course you're trusting the client. So how you are doing user authentication would change this answer somewhat.
Personally, I like membership. It's clean, easy, fast and can be scaled nicely if you end up having additional requirements. Doing something like this would be even easier with membership, since then you can actually use Roles.GetRolesForUser(); and only return the admin view if they contain the role you are looking for.

Profile variables in asp.net tracking session with login control?

I have been making a web site with a cart in asp.net using visual studio 2010. My question is concerning the Profile variable and Login Control.
I followed a pretty straight forward tutorial to add a cart to my site.
1: Shopping Cart Example
As you can see in the shopping cart tutorial, the author used a Profile to keep track of the cart.
When I was making this, I had expected the cart to stay the same with each different user login since we were using a profile and not a session variable. Fortunately, the cart would in fact reset as I logged in as different users with the login control.
So my question is, how is the Profile keeping track of the cart for each user. I'm almost certain that the login-control does not set a session variable, so I don't think the Profile object is auto-detecting a different user from the login-control... is it?
Please help me understand this, the author isn't quite clear.
Thanks a lot!
Basically the way it works is by using the authentication information to identify the user. So when a request comes in from an authenticated user the framework uses the username (typically in the form of an authentication cookie) to load the profile information into the current request.
In the case of the example you provided because the author is using <anonymousIdentification enabled="true"/> which allows for profile information to be available for anonymous users as well.
When an anonymous user makes a request, the AnonymousIdentificationModule module creates a GUID and writes it into a persistent cookie named .ASPXANONYMOUS. This GUID will act as the username for the purpose of the ProfileProvider.
the important part of the code that brings together the cart and the Profile is at the very end (happens behind the scenes for every login):
void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs e)
{
ProfileCommon anonymousProfile = Profile.GetProfile(e.AnonymousID);
if (anonymousProfile.SCart != null)
{
if (Profile.SCart == null)
Profile.SCart = new ShoppingCartExample.Cart();
Profile.SCart.Items.AddRange(anonymousProfile.SCart.Items);
anonymousProfile.SCart = null;
}
ProfileManager.DeleteProfile(e.AnonymousID);
AnonymousIdentificationModule.ClearAnonymousIdentifier();
}
You can read about Profiles etc on MSDN - for example: http://msdn.microsoft.com/en-us/library/ewfkf772.aspx
This is not quite entirely true about session. Sessions are used in a way to store certain information about logged in users. However information about logged in user (as set by asp:Login control after successful login) is also stored in a principal which you can access from HttpContext.Current.User object. Another location where information about users is stored is in the cookie named .ASPXAUTH cookie. So there are couple of locations from which user information can be retrieved. But Profile will rely on an object of type IPrincipal. As for the anonymous users, Peter Mourfield gave you a good answer so I will not repeat his words.

Categories