How can I set maxInvalidPasswordAttempts for a particular user role - c#

In my application there are different user roles like admin, user, superuser. I am using ASP .net membership provider in my application. In my machine.config file the maxInvalidPasswordAttempts is set to 5 which is default for all users. My issue is that, even for a admin user, the maximum invalid password attempts is 5. I need to change the maximum invalid password attempts for the admin user only. Please help.

I don't think that is going to be possible with the default provider. Since the MaxInvalidPasswordAttempts is not even persisted in the database, as far as I can tell. You will probably need to think about writing a derived Membership provider that implements this additional layer.
public class myMembershipProvider : System.Web.Security.SqlMembershipProvider
{
public override int MaxInvalidPasswordAttempts
{
get
{
//Check to the role of the user....and pass back the attempts allowed for them
if (HttpContext.Current.User.IsInRole(Admin))
{
return 9999; whatever...
}
return base.MaxInvalidPasswordAttempts;
}
}
}

Related

Understanding MVC5 UserClaim Table

I have been doing a lot of research but none resulted in helping me understand what is the point of UserClaim Table.
When you create a MVC5 project, there are some default tables created upon your database being registered. I understand the purpose of all of them except UserClaim.
From my understanding, User Claims are basically key pair values about the user. For example if I want to have a FavouriteBook field, I can add that field to the user table and access it. Actually I already have something like that built in. Each of my users have "Custom URL" And so I have created a claim in the following way:
public class User : IdentityUser
{
public string CustomUrl { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.AddClaim(new Claim("CustomUrl", CustomUrl));
return userIdentity;
}
}
public static class UsersCustomUrl
{
public static string GetCustomUrl(this IIdentity identity)
{
var claim = ((ClaimsIdentity)identity).FindFirst("CustomUrl");
return (claim != null) ? claim.Value : string.Empty;
}
}
Above basically allows me to access the CustomUrl by simply calling User.Identity.GetCustomUrl()
The above code won't write to the UserClaims table as the value exists in the Users Table. So what is the point of this table?
I am speculating that maybe I should add CustomUrl to UserClaims and somehow bind that to identity and that may what it is for? I would love to know the answer!
Claims are really useful in cases where you present multiple ways in which your users can register / sign on with your website... in particular, I'm talking about third-party authentication with organisations such as Google, Facebook and Twitter.
After a user has authenticated themselves through their chosen third party, that third party will disclose a set of claims to you, a set of information that describes the user in a way that you can identify them.
What information the claims will contain varies from provider to provider. For example, Google will share the users email address, their first name, their last name but compare that to Twitter... Twitter doesn't share any of that, you receive the identifier of their Twitter account along with their access tokens.
Claims based authentication provides a simple method to facilitate all this information, whilst the alternative may very well have meant creating tables in your database for each individual provider you worked with.

How to pass current context to an object c#

I am creating an application where I first login with my user account. This user account could be windows or self managed account in my own application database.
Now I want to authorize the logged in user before accessing any business objects of my application. Objects are mapped with database tables so eventually I want to authorize user first, whether to give data back to user or not.
After logging in I store user credentials globally as an object of UserCredential class. But I don't want to pass this credentials to each object when I am creating it.
Is there any way to check/reach the application context (including UserCredential object I stored globally) for each business objects automatically which I am creating further?
I want to achieve this in C#. Code example is much appreciated.
You should take a look at the PrincipalPermissionAttribute class, here is the MSDN documentation:
PrincipalPermissionAttribute class MSDN documentation
The PrincipalPermissionAttribute throws a SecurityException when the Thread.CurrentPrincipal does not match the security assertion.
Examples:
User's name is GDroid:
[PrincipalPermission(SecurityAction.Demand, Name = "GDroid")]
public void YourBusinessMethod()
{
// Do something
}
User belongs to Admin role:
[PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
public void YourBusinessMethod()
{
// Do something
}
User is authenticated:
[PrincipalPermission(SecurityAction.Demand, Authenticated = true)]
public void YourBusinessMethod()
{
// Do something
}

ASP.NET MVC login controller method without using a custom membership provider?

I'm very curious as to why I need to create a custom MembershipProvider and not supposed to do something like this to login a potential user.
[HttpPost]
public ActionResult Login(string username, string password)
{
UserUnitOfWork unitOfWork = new UserUnitOfWork();
User user = unitOfWork.UserRepository.GetByUsername(username);
if (user != null)
{
SaltedHashHelper saltHelper = new SaltedHashHelper();
if (saltHelper.VerifyHashString(username, user.Password, user.Salt))
FormsAuthentication.SetAuthCookie(user.Username, false);
}
else
{
// User cannot be verified.
}
return View();
}
If I create a custom MembershipProvider then I will have to create a custom MembershipUser because I am not using asp.net membership tables. I feel like that is more of a headache when your not using the aspnet membership tables. Maybe I am wrong.
Does anybody see anything wrong with my approach above? I'm curious.
Your approach is fine so long properly salt and hash the passwords and properly protect yourself from SQL injection.
The built in providers will be better tested than your custom built authentication provider, and may be more secure depending on your implementation.
You don't need to create a custom membership provider, you can use what ASP.NET gives you right out of the box. In fact implementing your own authentication scheme is always inadvisable if there's any other way out of it whatsoever. Worst case, just override the provider methods that you really need to behave differently.
Have a look at OWASP Top 10 for .NET developers part 7: Insecure Cryptographic Storage for some more background on why this is a bad idea.

Impersonating a user in ASP.NET MVC for testing

Is there an easy way to substitute current User object (the one inside controller) with IPrincipal having properties of another user? I'm thinking about environment that users Windows authentication and AD groups, so it's desirable to replicate all AD properties.
The "hard" way is to do LDAP query and implement IPrincipal interface, but I want to avoid that.
I solved this by adding a property like this to my base controller:
new public IPrincipal User
{ //we override User for impersonation
get {
if (/*check for impersonation*/)
{
return /*impersonated*/;
}
else
{
return base.User;
}
}
}
Create an interface/class to wrap the access to the current user object. Your custom service can return the user object or whatever you would like, and it will be easy to mock up in tests.

Authorising Web App users against User Information as well as Role

I was wondering if anyone would be able to help me with the following?
I need some more complicated rules for authorisation in a webapp than just role, which I have working fine. Something along the lines of "Allow all Admins. Allow Buyers, provided they have the correct department ID and are allowed to see this customer's credentials".
I am using a custom identity and custom principal to store information such as whether a user is allowed to see all clients or which individual clients they may see. This information is retrieved from a database and added upon creation of the identity/principal.
I have created a custom permission that extends IPermission, ISecurityEncodable. Within this, I have modified the Demand() function to the following:
public void Demand()
{
this._identity = (UserIdentity)Thread.CurrentPrincipal.Identity;
if (Thread.CurrentPrincipal.IsInRole("Admin")) { }
else if ((Thread.CurrentPrincipal.IsInRole("Buyer")) &&
(this._identity.CanViewAllClients) &&
(this._identity.IsInDept(this._departmentID)) ) { }
else if ((Thread.CurrentPrincipal.IsInRole("Buyer")) &&
(this._identity.CanViewClient(this._requestedClient)) &&
(this._identity.IsInDept(this._departmentID)) ) { }
else { throw new SecurityException("Custom Permission Denied"); }
}
I then call this when I wish to authorise by using
CustomPermission custperm = new CustomPermission(requestedClient, reqClientDept);
custperm.Demand();
This works fine, but seems a messy, hacky way to do things. Especially since it would be nice to use my security roles as an attribute e.g.
[PrincipalPermission(SecurityAction.Demand, Authenticated = true)]
public class...
Perhaps there is a way to call [CustomPrincipalPermission(SecurityAction.Demand, Authorised = true)] with a custom IsAuthorised check? Is this possible? What would need to be implemented?
I apologise if there is a simple solution that I've missed online, but rest assured I have been checking for days now.
It seems like what you want is a declarative rather than a programmatic demand. In order to do so, you'll need to create a CustomPermissionAttribute based on your CustomPermission.
There's an example of a declarative demand of a custom permission here and details of creating a custom permission attribute here.

Categories