I'm writing a credential provider that would correct user's password when the user is logging into Windows account and accidentally types password using wrong keyboard language settings (Ukrainian rather than latin for example). The same keys but different letters. Now I need a way to intercept the user-entered password and if it is entered wrongly to correct it. As a starting point I'm using the credentials provider from the Windows SDK. It works fine in a standard mode (like the default CP). But I cannot find where to obtain and correct the password entered by the user. I thought that HRESULT CSampleCredential::GetStringValue( DWORD dwFieldID, PWSTR* ppwz)
method is the right place to do it. To replace
hr = SHStrDupW(_rgFieldStrings[dwFieldID], ppwz);
string with
hr = SHStrDupW(ppwstrCorrected, ppwz);
Where ppwstrCorrected contains either the original password or the corrected one. But this does nothing. Credentials Provider continues to work as it did. I even tried to "break" my provider by making GetStringValue return some gibberish any time it is called. But the sample provider still works as a standard one. And yes, I've tried to log in via the sample provider and not the standard since they are easy to distinguish by bitmaps on their tiles. So where can I intercept the entered password that goes into Windows for checking?
I think it will be better to re-set corrected password back using ICredentialProviderCredentialEvents::SetFieldString()
ICredentialProviderCredential::GetStringValue() called by LogonUI to retrieve values of static text fields.
Answering my own question. There were two problems with my provider. First, provider's code was simply unused and standard provider's code was used instead. I don't know why it is so but I solved this by filtering out the standard providers, like it is described in Windows Credential Provider, Filter, and Unlock Workstation Scenario question.
Now, as far as SDK example is concerned, the unmodified user-entered password may be accessed in the CSampleCredential::GetSerialization() method. It is stored in _rgFieldString[SFI_PASSWORD] string. The password may be passed to the encryption function from this method, so it should be modified before it is encrypted.
Related
This is my first time using Backpack and I have a question about the base.php Backpack config. One of the keys there is called passwords and it has this random string value as shown in the screenshot below.
For the life of me I don't know what that means. The only thing I know so far is that the Forgot Password form submits to a page with the following error.
InvalidArgumentException
Password resetter [c45#$%TCC)*$%tc;pvctHJ^] is not defined.
When I set the passwords config value to null, the form works but the Reset Password link from the email shows a link like:
<mydomain>/password/reset?token=a67b566284a8415923f799682a50509cfd6ae11e4ea0f6e3026271a5446c1f61&email=xxx
instead of:
<mydomain>/password/reset/a67b566284a8415923f799682a50509cfd6ae11e4ea0f6e3026271a5446c1f61?email=xxx
So it is not matching the route defined in Backpack. But I guess that is another topic.
For now I just need to understand what the passwords config does and why is the value set like it currently is. Can anyone please explain?
That config should hold the name of the password broker that Backpack uses inside the Authentication.
It should NOT be gibberish, but the actual name of the password broker to be used. By default that's backpack as you can see in our demo. If commented out, it will use the same password broker that the stock Laravel Auth uses - as explained in the comment. I recommend you write backpack there - that should fix it for you.
This value should only be changed when you want to customize the authentication, and have mixed auth for users and admins, things like that. It uses Laravel's authentication, which is unnecessarily complicated if you ask me, but that's where the password broker concept is from.
We have a web application in .NET Core in which you can reset your password (such functionality much wow) using the ResetPasswordAsync(user, token, password) method of the UserManager class. We have the default settings about password validation (should be more than 6 symbols long, containing a digit, upper and lower character, a special symbol, etc). Everything works fine until you try to reset your password to one containing a + symbol. In that case the method returns a success but then you can't login with that password.
For example, if we have the password "Someth1ng_" it works, but if we have "Someth1ng+" it doesn't work. There are problems with other special symbols but we haven't taken the time to find out exactly which ones (the following are ok: *=_).
We've already checked whether the problem is with parameter passing from the client to the server and it's not - on the server the password is received as it was sent.
Could the problem be in the ResetPasswordAsync method? Has anybody had a similar issue?
I am having a similar issue, in my case I found that some passwords may affect login as ssnaky described before, in my case the password failed when I entered durga%118 at first I thought that the char % was the responsable but then I entered the new password durga%%%% and it worked fine, so I asume that maybe is something within the ResetPasswordAsync method.
NOTE: I found my problem, it was an encoding issue at the login section.
I'm new in LDAP. Perhaps the question may seem strange, but on the internet I have seen different versions. Please, help to understand which way is the correct authentication via LDAP. I have an LDAP-directory where user passwords are stored as hashes. I know two ways to authenticate third-party applications using the LDAP-directory:
Authentication check on the LDAP side. Using the “bind” function the DN and password of user are passed in plain-text. If the bind is successful user authenticate, otherwise doesn't.
Authentication check on the application side. Using the function “bind” we connect to the directory as an admin. We are looking for the right user and get his record. We parse password field, isolating the type of hash algorithm (e.g. {CRYPT}). We make hash of the user-entered password with proper algorithm. If the hashes are the same then the authentication is successful, otherwise not. (That is, the application must maintain an appropriate hash algorithm).
Which option is the most correct? And which way is considered a standard for any-vendor systems which claim support for LDAP-authentication?
You'll want to use Option 1!!!!!
Option 2 has some disadvantages:
You'll need an admin account that can read the passwords to be able to compare them to the one you hashed. That means that the application is able to read the password hashed. I'd consider that a bad idea.
You'll circumvent additional security measurements implemented. The password you are checking might be the right one. But due to other policies the user might be locked and should not be able to login. And failed attempts will not count towards a possible lockout.
The hashing algorithm might change in future to one you haven't implemented yet.
You might be able to circumvent those obstacles but you will need aditional code to implement that. And that effort has already been taken and is readily availabel when you use option 1
There is a common requirement of storing user credentials securely (user id / user password) in the App and use them automatically next time the App starts, but I'm not being able to figure out how to do this without user interaction.
Using JSON Store I need a password to encrypt the information, so if I store user credentials in the JSON Store I will need to ask to the user for the password used to encrypt the information.
A solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
As explained in the comments this is a really bad idea.
Is there any solution to store user credentials securely and recover them without user interaction?
You can use the Keychain API on iOS. Android doesn't seem to have an equivalent API.
The most complete solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
I would strongly advise against doing that, if you store the encryption key (the user id) in plain text, then the attacker can simply use that to get to the password.
Update (Aug 27, 2014)
You should consider:
Hashing - You could hash values you want to protect. These are one-way functions, so you can't get the password back once you hash it. However, you can verify that the user provided the correct password. For example: First login you store( hash(password) ) then on next logins you compare if hash(password_provided) == stored_password_hash. If it matches, the user provided the same password. You should also use a salt.
You could give the user the ability set a pin using some library like ABPadLockScreen (you could probably find or implement something similar for Android too). You can then use the pin as the PBKDF2 input to generate an encryption key (JSONStore will do this for you when you pass the pin as the password). I would advise in favor of letting users only try a small amount of incorrect pin numbers, especially if the pin is only numeric and short, that way they can't easily guess the pin by trying various combinations. The idea here is that a pin will be easier to remember and type than their password.
FYI - There's a Stack Exchange site similar to StackOverflow but for security questions here.
I'm reading about Federated Login for Google Account Users to figure out how I can have a user log in to a web application using their Google Account.
So towards the end of the process, Google returns a Google supplied identifier which is appended as openid.claimed_id. This means the web application uses this identifier to recognize the user and allow access to application features and data. My question is, is this identifier static? Can I use this identifier to repeatedly id the same user?
Yes. Consider the openid.claimed_id value to be the username. Especially with Google, but this is true for any OpenID Provider that truly implements 'directed identity', don't consider this username to be correlatible with other web sites. Any other relying party besides your own web site will get a different claimed_id value for the same Google user, by design.
Also, be sure to treat this claimed_id as case sensitive.
The specific answer to your question is found in Googles OpenID API documentation:
The Google-supplied identifier, which has no connection to the user's actual Google account name or password, is a persistent value; it remains constant even if the user changes their Google user name and/or email address. This identifier is also a "directed identity", that is, Google returns a different value to each relying party. Google uses the request parameter openid.realm to recognize the relying party, so if the third-party application decides to change this value, all user identifiers will change.
In fact, I just ran into an instance where the google claimed_id had changed for my test user. I was coming to the end of implementing OpenID into my app, and for no apparently reason the claimed_id in the response data is had changed.
I've been testing with this account for the past couple weeks, and the claimed_id was the same this entire time, as expected. Then wham, changed! I looked at the response data many times to verify, and the underlying code to retrieve the data had not changed.
I'm not sure how to handle this at the moment, but I think this is going to throw me for a loop. After initial authentication, users register to the site (as you might expect) and setup a screen name. How are we to verify it is the same user if the claimed_id had changed? We certainly can't use email address, per best practices.
EDIT
Now I have pie in my face! I missed one little detail, that turned out to be a major detail. I change my development environment and was hosting on a different v-host. This effectively change the realm, and this will change the claimed_id response according to the docs.
This was a good lesson for me, as I was about to implement OID on a subdomain in which realm was being set automatically in my code. Now I saved myself a headache down the road, because I would not have been able to use the same user database across all other sub-domains without breaking identity.
updating realm
MORE INFO
Just as a side note - even if you are developing your OpenID solution for one of your subdomains, it might be prudent for you to specify realm to your top-level domain.
e.g., openid.realm = http://*.yourdomain.com
It will allow you to expand your sign-in page across all your subdomains and keep user identity across them.
(optional) Authenticated realm. Identifies the domain that the end
user is being asked to trust. (Example: "http://*.myexamplesite.com")
This value must be consistent with the domain defined in
openid.return_to. If this parameter is not defined, Google will use
the URL referenced in openid.return_to.