in my application i want to use the current logged in user details,
in HttpContext.User.Identity there are 'AuthenticationType', 'IsAuthenticated' and 'Name', I want some more details from database when user logged in to the system. Is there any way to extend this identity class?
As Daniel noted in his comment you're going to need to create your own implementation of IPrincipal. I'm going to assume that you're using MVC5. If so, then you're going to need to implement an authentication filter which will allow you to set the principal for the request. This authentication filter would go to the database, retrieve the fields you have added, and populate your IPrincipal implementation. Finally, you would need to globally register that filter in your FilterConfig.cs file in App_Start so that it will be applied to every controller action in the application without you having to type it over and over again.
Related
After they type in their password, should I keep a variable in server session storage like Session["loggedIn"] = true that I check when requests are made to pages that require a login, or is there a better/safer way this is traditionally done in ASP.NET?
No, do not keep this in a session variable. In fact, I would argue you should try not to use session for anything. Try to keep the HTTP communication as stateless as possible.
For authentication in ASP.NET MVC, you have 2 alternatives, but ultimately, the both end up working the same way: by writing an encrypted authentication cookie to the browser after you successfully log a user in.
The newer alternative was mentioned in a comment to the OP: Microsoft.AspNet.Identity. To use this, you should be using a newer version of ASP.NET MVC with the OWIN pipeline (though I am not sure if you have to). The older alternative is called Forms Authentication, and can be used with any version of MVC except version 6 (the new vNext / core 1.0 stuff) I believe.
When you have successfully integrated one of these 2 tools into your MVC application, after a user logs on, your Controllers will have a non-null User property of type IPrincipal. You can use this property to determine whether or not a user is authenticated:
// in a controller
bool isThereAUserLoggedIn = this.User != null && this.User.Identity.IsAuthenticated;
If you are using the newer Microsoft.AspNet.Identity, then this IPrincipal User property will be implemented as a ClaimsPrincipal with one or more ClaimsIdentitys. Forms Authentication does not do claims like this, so if you want claims, or social login, etc, use Microsoft.AspNet.Identity.
The way that this is traditionally done in ASP.NET and by my opinion also better and safer is by making use of the ASP.NET Identity package.
ASP.NET Identity handles all aspects around user accounts in a web application:
database for users, including roles and more
user registration and management, like register, email verification, log in, remember me option, forgot my password action and more.
user authentication & authorization
Just to make things more clear, authentication means that the user making the request is actually a valid application user and authorization means that the user has the authority to perform the requested action.
Practically, when a user logs in, Identity automatically keeps that information and makes it available in all controllers and views under User property. So you know at any time which user made the request. Identity also supplies each request with a cookie used for user authentication and authorization.
To check for user authentication you use the User.Identity.IsAuthenticated in a view and the Authorize attribute in a controller:
[Authorize]
public ActionResult Create( ... ){ ... }
The above use of the Authorize attribute will allow only to registered users to request this page.
It is also very common to extend the functionality of your application to include roles for the users and user authorization. Identity creates a "Users" table, a "Roles" table and a many to many relationship between them. After assigning roles to your users you can authorize their requests by using User.Identity.IsInRole("YourRoleName") in a view and in a controller:
[Authorize("YourRoleName")]
public ActionResult Create( ... ){ ... }
The above use of the Authorize attribute will allow only to registered users having the "YourRoleName" role to request this page. In any case if Identity fails to authenticate or authorize the request will prompt to the log in page.
ASP.NET Identity is simple to use, it works and it is easy to extend the membership functionality of your application both by making use the many tools supplied with it and overriding its classes to give them a more specific or complex behaviour.
You will find infinite help on the web on how to use it or a step by step guide.
Im using asp.net identity and I have a number of user classes that inherit from IdentityUser.
Lets say I have an inheritance chain like:
IdentityUser <- AppUser <- ServiceUser <- ServiceEmployee and ServiceCustomer (which both inherit from ServiceUser).
When trying to create a unified login form whats the best strategy?
If you use the OTB account controller and change the UserManager to use ServiceUser but try to login an account that was registered as ServiceEmployee it will fail because FindAsync() apparently only tries to find based on "ServiceEmployee" in the discriminator field, so if the account was registered as a different "type" it cant be used to login. So this happens with any combination when registered vs login types differ.
Should I update the login action to use multiple UserManagers so that there is a check against each user type or is there some better way to do what I am trying to achieve.
Thanks for any info.
Have you considered keeping your identity users and your own application users separate? Meaning User is what holds your identity information and Person is what the rest of your application uses (and other types such as Employee inherit from). This is how I do it myself. I keep all security/identity stuff completely separate (in separate project/context) and only link my User and Person entities which works great for me - much easier to maintain and update my security model without affecting the rest of my application and (as much).
I'm new to ASP.NET MVC world. I'm building an intranet web application. Authentication and authorization is defined in my case as below:
Authentication: If HttpRequest contains an Header with "USER_ID", user is authenticated.
Authorization: There is one in-house WCF Service, which returns list of roles user is entitled to taking USER_ID as input. I keep the roles required by my application in xml file. If user's required role is in svc response then, she is allowed to use the application.
I'm thinking of implementing it like below:
In Global.asax - > Application_AuthenticateRequest, I'll put code to check http Header. If its non_blank, I'll let user to go through this stage.
In OnAuthorization method of AuthorizeAttribute class, I'll put code to fetch role list and match it against required roles from xml file.
Is there any way that I can use existing authentication,authorization infrastructure?
I see code like this
[Authorize(Roles = "admin")]
public string Index() {
return "only admins!";
}
How can I link Roles property like above to some Xml or Table instead of hard coding?
Please help me to implement this logic in asp.net mvc application.
You should check Windows Identity Foundation (WIF), in particular ClaimsAuthorizationManager and ClaimsPrincipalPermissionAttribute. The later allow you to specify what operation and resource need to be secured, while in ClaimsAuthorizationManager you can check whether the current user can perform the operation on the resource, and that can be read from any source you desire.
For Authorization, I would either:
Create a GenericPrincipal in the global.asax AuthorizeRequest event handler with the appropriate roles, and assign it to both HttpContext.User and Thread.CurrentPrincipal.
Or (better), write a custom RoleProvider that gets the users roles from the xml file. If you configure such a RoleProvider, ASP.NET will assign a suitable RolePrincipal to both HttpContext.User and Thread.CurrentPrincipal.
You can then use the standard AuthorizeAttribute.
I'm building an web application that I want users to have specific permissions to perform a specific action. I don't want to use the default permission and role providers in ASP.NET.
I was thinking of having each User associated with a Role. Each Role is mapped to a set of Permissions (CreatePost, ReadPost, UpdatePost, DeletePost and so on).
I have a couple of questions regarding this. Would it be best to have a boolean property for each Permission on the role or some sort of bitfield? I like the idea of having methods for this but properly need to map these to the permissions stored for the role in the database.
Also, how would I implement this for each action/request? I'm thinking something along the lines of what was posted here but I'm not really sure.
Thanks!
Make your own role provider and register it in the web.config. Look at the MSDN for a sample. Once it is registered it will associate the roles you provide with the principal.
I've just done that for one of my project and it works fine.
To check whether the user has permission to execute a task you'll have to see whether the user is in the required role. In "normal" ASP.NET you will have to do this in code. In MVC you can do that with attributes on each class/method in the controller.
I am writing an MVC app that has two branches to travel along right from the beginning. On path authorizes with a PIN and I am using forms authentication to limit access to this section of the code. However, the other path will accept an AD log in and I need stop people from move between the branches using URLs. Should I be using a custom routing or should I create two separate authorization attributes to restrict access.
Thanks
You could use Roles to handle this with the existing AuthorizeAttribute. Simply put your AD-authorized users into a particular role, then in the paths that require an AD-logon set the Roles for that controller/method to require the AD role. This would entail implementing a RoleProvider which can seem somewhat daunting, but really isn't all that bad. Cache the user's roles in a cookie so that you don't need to look them up every time. The advantage here is that this will scale to additional roles as your application gets more complex.
Alternatively, you could extend the existing AuthorizeAttribute, overriding OnAuthorization and use your custom version. This attribute could check to make sure that not only is the request authorized, but that it has the proper credential type. The credential type could be stored in the session on login and retrieved from there for authenticated users. This is simpler to write, but doesn't scale as well.