we have two part for authentication in web site. the first use in admin and the second use for users to enter to site.when admin authentication in site and go to user page ,make error.how to create different authentication for those?web config code:
<authentication mode="Forms">
<forms loginUrl="~/admin/Login.aspx" timeout="2880" />
</authentication>
Based on your reply in comments...
we read users permissions on sign on.when i use User.Identity.IsAuthenticated then its return true.but this Authenticated for admin.how to make different Authenticated for users?
Checking whether a user is authenticated is different from checking a user's permissions. Authentication only tells you that the person visiting your site has authenticated themselves (i.e. logged on to their account).
What's missing in your equation is the authorization phase (Remember college/uni? Everyone is issued ID cards, on access to the college/uni grounds you authenticate yourself, staff members also authenticate themselves, students won't have authorization to enter the staff room or perform certain tasks, but staff members do).
We implement this using what's called Roles, every user should have a Role. Every Role should have a set of Permissions associated with it, for now I wouldn't worry about Permissions as it can get real complicated real quick, if you focus on ìmplementing roles alone for now, it would be enough to get you going.
Once every user has a role associated to their account, you can check their Role instead of whether they're simply authenticated, which doesn't tell you much.
There should be an extension method to the IPrinciple interface along the lines of GetUserRoles() already implemented in framework, User.Identity.GetUserRoles() something along the lines of that.
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.
I have a system where if the user logs in as Joe with the role "Readonly" then he will be granted access only to read things (fairly obviously) however if he logs in as Joe with the role "Administrator" then he will have access to do administrative functions. However I want him to have to relogin if he wishes to change from the Readonly role to the Administrator role so that he could potentially leave his account logged in as Readonly on a display screen or something without fear of someone hijacking his Administrator priviledges.
Now I also need to be able to log in a Web client via an implicit grant or another server via a code grant and have that service be able to use the same roles as well (while still requiring Joe to log in as the particular role if he isn't already authenticated.)
Now I have been trying to do this with IdentityServer3 but I cant seem to get the role information to be part of the authentication for the user, I tried adding an acr_value of role:ReadOnly to the token request (which then turns into an authentication request if the user is not logged in) but if they log in with the acr_value of ReadOnly and then come back to log in with the acr_value of Adminstrator it just lets them on in because they are already authenticated as the user.
Any tips on what I should be using instead of what I am doing or how I might be completely off base in this OAuth2/OpenID Connect world?
I finally figured it out so for others who might want to do the same thing here is what I did.
First you have build a custom UserService that looks in the acr_values for extra information. Then create a claim for that extra information in the AuthenticateResult.
Second you have to override the ClaimProvider to include your custom claim set in step one in the tokens generated.
Next you need a CustomRequestValidator in order to check if a new acr_value is being set compared to the one you have stored in token being currently used. If it has changed and you want to force the user to reauthenticate you can set 'request.PromptMode = "login";'
And that is it, using that set of steps I can now authenticate a user using 3 values (username, password, and role) and if the role requested changes I can require them to reauthenticate.
Works swimingly.
I m using Angularjs project and using Asp.net identity custom storage provider with Enterprise library for token authentication.
Implemented custom userstore to create an account.
[Authorize] attribute works well after logged in. i want to restrict the method for particular user.
So tried to implement [Authorize(Roles="Admin,User")].
Here one user can have two roles in practical. But as per the system, when user login, we restrict the user to select the particular role.
So, after validated by asp.net identity, user should select any one of the role.
Here my need is,
I want to maintain the role which he selected (we consider this concept like impersonate user, but not exactly).
Or,
Need to implement in the Authorize attribute itself.
I've seen some of the examples like we can add claim to identity.
But I can add custom claims only inside the method,
GenerateUserIdentityAsync
in my case I need to add claim after log in validated. I've gone through some example and implemented like following.
ClaimsIdentity identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaim(new Claim(ClaimTypes.Role, "Test"));
After added claim, when I try to get the claim to check the logged in user role,
List<Claim> claim = claims.Where(c => c.Type == ClaimTypes.Role).ToList();
I didn't get the Role "Test".
Here my bad luck is, in claims, I've all the roles of the user except role = test
How to authorize the user role or maintain logged in here..
I see at least three solutions for your problem:
Use a claim transformation to filter the role claims, to match a role the user choose. You can use a claim transformation middleware or you can filter the claims during login (be aware, that you do not know the user roles BEFORE login, and afterwards filtering might be too late). PRO Does not necessarily need session state; CON User can not choose during runtime.
Store the role in the session and authenticate against that role. Make sure, that you check against the role claims, when the user chooses his role. PRO User might change role without re-sign-in. CON Needs session state (Might be an issue in farm environments).
Don't do it at all and I'm totally serious about that. Provide your user a clean interface, that makes him know, what role he has and use areas and other technics to separate the concerns.
I am working on an ASP.NET MVC5 web app that has the following relevant properties:
Uses MVC5.1, Identity 2.0, not restricted to any legacy stuff - can use newest everything.
A user belongs to at least one organization.
Each organization has at least one user that is an organization admin.
The organization admin can allow users specific rights, such as becoming another organization admin.
From what I have understood, a good way to handle this would be to use claims.
In addition to the default claims, a user could then typically have the following claims:
Organization: {some guid}
Organization-Admin: {same guid as above}
Organization-Publisher: {same guid again}
There could potentially be super-admins, or even super-users, with claims giving them access to different roles in multiple organizations.
Now, lets imagine I am user admin logged on to my administration panel, and I want to grant user user the Organization-Publisher claim for an organization that I have the Organization-Admin claim for.
For simplicity, I have a model object that would look something like this:
public class GrantRightModel
{
public string OrganizationId { get; set; }
public string UserId { get; set; }
public string Right { get; set; }
}
and for the purposes of this example, we get the following values from our admin user:
OrganizationId: The GUID of an organization that admin has an Organization-Admin claim for.
UserId: user
Right: Organization-Publisher
There are a number of things that have evaded me about this way of doing things. Lets say we have an OrgAdmin controller with a GrantRight action;
Will the controller action need to check that the currently logged in user (found using for instance ClaimsPrincipal.Current) has the Organizaton-Admin claim for GrantRightModel.OrganizationId "manually", or are there clever auth attributes for this kind of thing?
What is the correct way in code to add the Organization-Publisher: {guid} claim to user? My controller will get a UserManager as necessary by dependency injection.
If user is signed in to the application when this happens, is there a way to have him automatically have the correct claim starting with his next request? I've seen mentioned ways to do this that would cause the user to be logged out, so that he would log in again and start a fresh session with his new claims. I see why that is the way it is, but given that the user could be working on something that takes a lot of time, it might not be popular to just have him logged out when he tries to submit his work.
There is a bit of information on this on the web, but my google-fu has failed me in finding the one that shows me how to beat these three points.
Anyone?
Thanks!
Regardins your questions.
Will the controller action need to check that the currently logged in user (found using for instance ClaimsPrincipal.Current) has the Organizaton-Admin claim for GrantRightModel.OrganizationId "manually", or are there clever auth attributes for this kind of thing?
No. The Authorize attribute takes an optional list of roles that are checked upon authorization. If one of role claims points to that role, used is authorized with no custom code involved.
What is the correct way in code to add the Organization-Publisher: {guid} claim to user? My controller will get a UserManager as necessary by dependency injection.
You create the ClaimsIdentity with proper claims and then ask the authorization manager to sign in used with the identity. The identity is typically then persisted in a cookie together with claims.
If user is signed in to the application when this happens, is there a way to have him automatically have the correct claim starting with his next request? I've seen mentioned ways to do this that would cause the user to be logged out, so that he would log in again and start a fresh session with his new claims. I see why that is the way it is, but given that the user could be working on something that takes a lot of time, it might not be popular to just have him logged out when he tries to submit his work.
I've read it twice and don't quite get it. When you issue a cookie, the cookie is responsible for retaining the authenticated session. Claims are then rebuilt early in each request pipeline based on the cookie. Numerous requests can be then issued by the user and he is still "logged in" as long as the cookie is not invalidated or the auth token stored in the cookie expires.
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.