How do I administratively set a new password for ASP.net Identity User who forgot their password? - passwords

I am not looking for a solution that involves the user, a token generated, and emailing in order to reset a user's password.
The scenario is a user contacts the admins and asks them to reset their password (internal organization web app). They are then told what that new temporary password is so they can log in and change it.
I see no function that lets me do the above. My attempt:
string passwordToken = await UM.GeneratePasswordResetTokenAsync(user.Id);
IdentityResult res = await UM.ResetPasswordAsync(user.Id, passwordToken, "newPassword##!$%");
UM is UserManager.
I get error "No IUserTokenProvider is registered". I think GeneratePasswordResetToken is the one causing the error. If so, why?
How do I properly do what I need?

Use the combination of RemovePasswordAsync and AddPasswordAsync
UserManager.RemovePasswordAsync(user.Id);
UserManager.AddPasswordAsync(user.Id, tempPassword);

Related

How to connect LDAP With username and password?

I have my Ldap working the only issue i'm facing was when I try to login with email that is when I land in the else part in the below code. If my username is different from email then it throws error. i.e if my email is 'skumar#gmail.com' and my username is 'saurakumar' then it will through invalid username password error.
As internally I'm using username to make email i.e if the user login with name 'karan' then i'm expecting the email to be karan #gmail.com which is not true in many scenario and the Authentication fails. I'm looking for some solution wherein I can login either via email or via username I'll be able to authenticate user. Below is the snippet of my code. Please suggest?
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
ldapEnv.put(Context.PROVIDER_URL, url);
ldapEnv.remove(Context.SECURITY_PROTOCOL);
if (email == null) {
lContext = new InitialLdapContext(ldapEnv, null);
entryResult = searchUserEntry(lContext, user, searchCtrls);
final String usrDN = ((Context) entryResult.getObject()).getNameInNamespace();
lContext.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
lContext.addToEnvironment(Context.SECURITY_PRINCIPAL, usrDN);
lContext.addToEnvironment(Context.SECURITY_CREDENTIALS, pass);
lContext.reconnect(null);
} else {
ldapEnv.put(Context.SECURITY_PRINCIPAL, email);
ldapEnv.put(Context.SECURITY_CREDENTIALS, credentials);
lContext = new InitialLdapContext(ldapEnv, null);
return lContext;
searchUserEntry(lContext, user, searchCtrls);
}
Normally this is a 3-step process:
Bind to LDAP as an administrative user. Note that this should not be the master user defined in the configuration file: that's for OpenLDAP's use itself. Instead it should be a user mentioned in the DIT that has the appropriate search access for the next step.
Search for the user via some unique attribute, e.g. in your case email.
Using the found DN of the user and the password he specified, attempt to bind as that user (with the reconnect() method, after changing the environment of the context appropriately).
If all that succeeds, you have a login success. If (2) or (3) fail, you have a failure, and note that you should not tell the user which it was: otherwise you are leaking information to attackers. You should not mention whether it was the username (email) or the password that was wrong.

Removing a user from backend created by IdentityServer4

I am debugging confirmation email flow when signing up a new User in Asp.Net Core web application with Identity Server 4.
Since I had already signed up with my actual email, to reuse it, I modified the UserName and Email in AspNetUsers table using SQL Update to some random value.
Now when I am signing up with the original email again. I am getting a duplicate user error
result = await _userManager.CreateAsync(user, model.Password);
I have already:
Cleared browser cache.
Closed local IIS Express
Restarted Visual Studio.
Used_userManager.DeleteAsync() after updating the UserName and Email back to original values but this gives an Microsoft.AspNetCore.Identity.IdentityError with description Optimistic concurrency failure, object has been modified.
On running this query on Sql Server
select * from INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME in ( 'UserName' , 'Email')
I get the following:
I know that this is not a good practice to mess with backend, but this is development environment and I could continue my work with another email.
I would request readers to help in understanding how the User could be safely scorched to be able to reuse the email.
Appreciate your time
I agree with Kyle's comment and to further speed up your debug process you should note that if you use gmail to do this you can debug this process using one email.
from google/gmails perspective myaccount#gmail.com == my.acount#gmail.com == m.y.a.c.c.ount#gmail.com etc etc just try it out, google disregards all period characters in the email. you can enumerate/exhaust ~2^8 emails (in this example) if you just enumerate through the local-part of the e-mail address. but from your applications side, myaccount#gmail.com is not the same as my.account#gmail.com, ie they are different user accounts. Basically you can use one email to test out this feature of yours without having to delete the user.
Here is how I did it and finally got passed the pesky "concurrency failure" error message... This works in ASP.NET CORE 2.2
Obtain the user object through the FindByName method first.
Remove the user from their assigned Role (in this case I hard coded "Admin" because that is the role I'm interested in but fill in your own), then delete the user.
//Delete user.
//Obtain the user object through the FindByName method first.
//Remove the user from their assigned Role, then delete the user.
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
ApplicationUser delAppUser = new ApplicationUser
{
Email = "SomeEmailForindividualAdminUser",
UserName = "SomeUsernameindividualAdminUser"
};
Task <ApplicationUser> taskGetUserAppUser = userManager.FindByNameAsync(delAppUser.UserName);
taskGetUserAppUser.Wait();
Task<IdentityResult> taskRemoveFromRoleAppUser = userManager.RemoveFromRoleAsync(taskGetUserAppUser.Result, "Admin");
taskRemoveFromRoleAppUser.Wait();
Task<IdentityResult> taskDeleteAppUser = userManager.DeleteAsync(taskGetUserAppUser.Result);
taskDeleteAppUser.Wait();

DirectoryEntry authentication throws COMException instead of DirectoryServicesCOMException

I'm using .NET and creating a DirectoryEntry and the access the NativeObject member to validate a user's credentials against AD.
There are some situations, where the login will fail, because the "User must change password on next logon" flag is set or the user is currently not allowed to logon because the logon times do not match.
I want to distinguish if one of these situations occured or if the user just entered a wrong password.
If I create the DirectoryEntry object with parameter AuthenticationTypes.None, a DirectoryServicesCOMException is thrown if the login failed. The information in this exception can be used to determine e.g. if the "password change" flag is set.
Unfortunately, using AuthenticationTypes.None is not a secure way, as the password is transmitted.
If I create the DirectoryEntry object with the parameter AuthenticationTypes.Secure, a COMException is thrown instead of a DirectoryServicesCOMException. This exception is very generic, as it always has the error code ERROR_LOGON_FAILURE. I cannot distinguish if the user has entered a bad password or if the password has to be changed.
MSDN documentation says: If AuthenticationTypes.Secure is set, the WinNT provider uses NTLM to authenticate the client. I guess this leads to a different behavior where only a COMException is thrown.
Works, but insecure:
var de = new DirectoryEntry(path, user, pass, AuthenticationTypes.None);
Secure, but throws only COMException:
var de = new DirectoryEntry(path, user, pass, AuthenticationTypes.Secure);
The first option uses basic authentication and throws specific DirectoryServicesCOMException, second option uses NTLM and throws only a generic COMException.
Has anyone an idea how I can detect if a user has to change the password, the account is locked or expired, logon times are invalid, ... or if the user has just entered a wrong password ?
Many thanks.

Accounts.registerLoginHandler with passwords in Meteor

I'm new to meteor and am stuck on registering a login handler that lets me use the password to authenticate the user.
I'm working off the code from http://meteorhacks.com
The server side code is as follows:
Accounts.registerLoginHandler(function(loginRequest) {
var userId = null;
var user = Meteor.users.findOne({'emails.address': loginRequest.email, password: loginRequest.password, 'proile.type': loginRequest.type});
if(user) {
userId = user._id;
}
return { id: userId}
This works fine if I take out the password field and just use the email and type ones. How do I get this working with the password as well?
Bottom line, you can't directly search via the plaintext password. You need to verify the password via SRP which is a little tricky as there isn't any documentation on it. Luckily Meteor is open source! A good start is at the accounts-password : https://github.com/meteor/meteor/blob/master/packages/accounts-password/password_server.js
There already is a package that can do password logins for you (the one the above file is from). You can add it to your project via meteor add accounts-password.
Then you could login with Meteor.loginWithPassword

DropboxUnlinkedException but the session already had token inside and user didn't revoke the access

My problem is I have existing user in database which store the key and secret from the first authentication. I wish to reuse it again when I come back. For the first time authentication, everything working fine. I can use every method call from Dropbox API and the Token(key and secret) was stored in database.
I come back to app and get the Token from database, set it to the session, link current session with API.
session = new WebAuthSession(appKeys, ACCESS_TYPE);
api = new DropboxAPI<WebAuthSession>(session);
String userKey = dropboxUserObj.getUserKey(); //Key from database
String userSecret = dropboxUserObj.getUserSecret();//Secret from database
AccessTokenPair userAccessTokenPair = new AccessTokenPair(userKey, userSecret);
session.setAccessTokenPair(userAccessTokenPair);
It return DropboxUnlinkedException to me when I want to get user data from api using
String userDisplayName = api.accountInfo().displayname;
I have checked on debug mode. Api was linked with the current session. The current session stored Appkey and user's token and correct access type. The point that I doubt is I saw "client = null". I maybe forgot something but I check them all, try every possibilities I can think of but it still return me "DropboxUnlinkedException" which mean I haven't set an access token pair on the session and I didn't revoke access for sure.
Please help me figure out...
I added a screenshot maybe it can illustrate my problem