Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
As a low level developer, I am working on a project on User Management using ASP.NET Identity in ASP.NET mvc.
Please how do I do the following:
Automatically lock the user after 5 failed login attempt.
Manually unlock the user by the Admin after a request.
Send e-mail to selected users based on role or even all users
How do I use the ASP.NET Identity in MVC to write the code for the user interface.
Thanks
You can set MaxFailedAccessAttemptsBeforeLockout=5 as in below. you can find this at
IdentityConfig.cs
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
And you can set shouldLockout equal to true in login then it makes lockout in 5 times.
await `SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);`
you can see below code in
Identityconfig.cs
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
According to the minutes, you set, will generate timestamp on AspNetUsers table LockoutEndDateUtc column.According to setup time, you can edit the time backward 5 minutes as in this scenario.You can do this using an interface for the particular requester querying by userid and modify LockoutEndDateUtc respectively.
3.Your roles are store in AspNetRoles table and users map their roles with AspnetUserRoles table. You can query particular roles and retrieve users mail address. Set up the mail server for sending emails.
here is code for setup Gmail
var SenderEmail = new MailAddress("sendermail", "");
var ReciverEmail = new MailAddress("Destinationmail", "");
var Password = "";
var subject = "";
var body = message.Body;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(SenderEmail.Address, Password)
};
using (var mess = new MailMessage(SenderEmail, ReciverEmail)
{
Subject = "",
Body = ""
})
{
smtp.Send(mess);
}
Related
So the users authenticate using AAD, but I need to get the role they have been allocated in the Database.
I have tried adding this to my openIdConnectAuthenticationOptions in my Startup.Auth as suggested in some posts:
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false, // Simplification (see note below)
//RoleClaimType = System.Security.Claims.ClaimTypes.Role
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
}
But no role is displayed when I check the claims while debugging. I assume this is because there is no login happening as it would when using SignInManager, so I tried doing an actual sign in after AAD authenticated successfully, as I have the user Id from the DB:
var user = db.Users.Where(x => x.Id == loggedInUserId).FirstOrDefault();
var userForIdentity = UserManager.FindById(user.Id);
if (user != null)
{
await SignInManager.SignInAsync(user, true, true);
}
I thought that if I do the above after the AAD signin, that the role would be added to allow me to make use of User.IsInRole("Administrator") for example, but it doesnt seem to add it.
I have seen some posts that say that we can edit the manifest in Azure AD on the app that was registered, but I dont have access to the clients AAD.
My question is, is there a way to make use of User.IsInRole("") based on what is in the DB after AAD sign in ?
Thanks for any help.
My application is using the AD Authentication for Login using LDAP URL. All was fine until our SA told us to change the URL to LDAPS. Once I added the URL as LDAPS it throws an exception and does not allow users to Login. Please help me in this.
Working LDAP URL: LDAP://reg1.abc.com
LDAPS URL (NEW) : LDAPS://reg1.abc.com (Not working once changed)
Below is the code to Authenticate user through LDAP.
public static SearchResult AuthenticateUser(string userName, string password)
{
var directoryEntry = new DirectoryEntry(ConfigurationManager.AppSettings["ActiveDirectoryPath"], userName, password, AuthenticationTypes.Secure);
var directorySearcher = new DirectorySearcher(directoryEntry);
directorySearcher.Filter = "(samaccountname=" + userName + ")";
var result = directorySearcher.FindOne();
return result;
}
That's a common question that might be already answered at Unknown Error (0x80005000) with LDAPS Connection. Follow that link and try to add port 636 and custom certificate validation:
LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier("server", port));
con.SessionOptions.SecureSocketLayer = true;
con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback);
con.Credential = new NetworkCredential(String.Empty, String.Empty);
con.AuthType = AuthType.Basic;
con.Bind();
In the given example Credential is using empty strings, that might need to be changed by real login/password if required.
I've built an MVC 5 app using Identity authorization. I have reset password functionality in place, and it works fine, for 99% of the users. However, I have a very small percentage of users who forget their passwords and are either intimitdated by the reset process or just cannot seem to do it correctly.
Is it possible for me to reset a password on behalf of someone else? It doesn't appear possible to do this, but wanted to verify.
If you want to change password directly yes you can do it.
var context = new ApplicationDbContext();
var store = new UserStore<ApplicationUser>(context);
var UserManager = new UserManager<ApplicationUser>(store);
String hashedNewPassword = UserManager.PasswordHasher.HashPassword("password_you_want");
ApplicationUser cUser = await store.FindByIdAsync(AspNetUserId);
await store.SetPasswordHashAsync(cUser, hashedNewPassword);
await store.UpdateAsync(cUser);
I have implemented the ForgotPassword (with token reset) into my MVC 5 application. We are in production. Although this works in majority of the cases, many of our end-users are of older age and get confused when they cannot login and need a reset. So in those situations, I am considering giving one of our admin staff the ability to reset a user's password and giving them the new password on the phone. The data is not that sensitive.
I tried this:
public ActionResult ResetPassword()
{ UserManager<IdentityUser> userManager =
new UserManager<IdentityUser>(new UserStore<IdentityUser>());
var user = userManager.FindByEmail("useremail.samplecom");
userManager.RemovePassword(user.Id);
userManager.AddPassword(user.Id, "newpassword");
}
I get a cryptic error stating Invalid Column EMail, Invalid Column Email Confirmed ......
I also tried the userManager.ResetPassword(), but abandoned that idea because it needs a token reset. I want to bypass it.
What am I not seeing?
Thanks in advance.
I also tried the userManager.ResetPassword(), but abandoned that idea because it needs a token reset. I want to bypass it.
How about you just generate the token and pass it to the Reset routine ?
var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
var code = await userManager.GeneratePasswordResetTokenAsync("username");
var result = await userManager.ResetPasswordAsync("username", code, "your new password");
if (!result.Succeeded)
{
//password does not meet standards
}
The idea here is you are just emulating/bypassing the usual routine of sending the token to the client (via email) and having the link that they click on call ResetPasswordAsync
I'm not completely sure if this will work in your implementation but I use the following code with success in a use case which has basically the same requirements as yours. The difference is that I'm not letting any user reset it's own password. This is always the task of an admin.
I'm bypassing the ApplicationUserManager and edit the information directly in the table, using just Entity Framework.
// I created an extension method to load the user from the context
// you will load it differently, but just for completeness
var user = db.LoadUser(id);
// some implementation of random password generator
var password = General.Hashing.GenerateRandomPassword();
var passwordHasher = new Microsoft.AspNet.Identity.PasswordHasher();
user.PasswordHash = passwordHasher.HashPassword(password);
db.SaveChanges();
You have to get the user from the database and generate the code not by username :
public async Task<Unit> ResetPassword(string userName, string password)
{
if (!string.IsNullOrWhiteSpace(userName))
{
var returnUser = await _userManager.Users.Where(x => x.UserName == userName).FirstOrDefaultAsync();
var code = await _userManager.GeneratePasswordResetTokenAsync(returnUser);
if (returnUser != null)
await _userManager.ResetPasswordAsync(returnUser, code, password);
}
return Unit.Value;
}
I would like to setup a multi-tenant ASP.NET MVC app. Ideally, this app would have a route with {tenant}/{controller}/{action}/{id}, each tenant representing an logical instance of the app (simply independent multi-user accounts)
The fine grained details how do that are still quite unclear to me. Any guide available to setup such multi-tenant scheme with ASP.NET MVC?
I am currently working on a similar project using ASP.Net MVC, Forms Authentication and the SQL providers for Membership/Roles/Profile. Here is the approach I am taking:
Register the default route as `{tenant}/{controller}/{action}/{id}
Change the default behavior of the FormsAuthenticationService that comes with the standard MVC template. It should set the UserData of the authentication ticket to include the tenant name (from your route).
public void SignIn(string userName, bool createPersistentCookie, string tenantName)
{
var ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30),
createPersistentCookie, tenantName);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
HttpContext.Current.Response.AppendCookie(cookie);
}
In your global.asax file to do some tenant security checking and allow partioning of users between tenants in one membership database
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
//Since this method is called on every request
//we want to fail as early as possible
if (!Request.IsAuthenticated) return;
var route = RouteTable.Routes.GetRouteData(new HttpContextWrapper(Context));
if (route == null || route.Route.GetType().Name == "IgnoreRouteInternal") return;
if (!(Context.User.Identity is FormsIdentity)) return;
//Get the current tenant specified in URL
var currentTenant = route.GetRequiredString("tenant");
//Get the tenant that that the user is logged into
//from the Forms Authentication Ticket
var id = (FormsIdentity)Context.User.Identity;
var userTenant = id.Ticket.UserData;
if (userTenant.Trim().ToLower() != currentTenant.Trim().ToLower())
{
//The user is attempting to access a different tenant
//than the one they logged into so sign them out
//an and redirect to the home page of the new tenant
//where they can sign back in (if they are authorized!)
FormsAuthentication.SignOut();
Response.Redirect("/" + currentTenant);
return;
}
//Set the application of the Sql Providers
//to the current tenant to support partitioning
//of users between tenants.
Membership.ApplicationName = currentTenant;
Roles.ApplicationName = currentTenant;
ProfileManager.ApplicationName = currentTenant;
}
Partition each tenants data. Here are two options:
4a. Use a separate database for each tenant. This provides the best data security for your tenants. In the shared membership database, add a table that is keyed on unique appid for each tenant and use this table to store and retrieve the connection string based on the current tenant.
4b. Store all data in one database and key each table on the unique tenant id. This provides slightly less data security for your tenants but uses only one SQL Server license.
You will prob find these links useful.