LDAP Password reset does not respect the pwdhistory attribute - java

I'm using Java - Apache Directory Client API for accessing Apache DS Ldap Server using ldapConnectionTemplate.
I'm trying to implement a feature which allows the user to reset/change the password. My password policy has a password history attribute value of 5. So user will not be able to use any of the previous 5 passwords.
When I'm using the modifyPassword method for changing the password(i.e. as a user by passing current and new password), it respects the password history policy. i.e I'm not allowed to use any of the previous 5 passwords and getting password exception as expected. But when using the reset option(i.e. - only new password), it does not honor the password policy. It accepts any value(including current one) and updates the password.
How to make the reset password scenario honor the password history policy? Any ideas, suggestions and solutions are welcome.

I don't believe the behaviour you desire is specified anywhere.
The idea of a 'reset' in the sense you mean is that the admin sets it to something known, tells the user what it is, and the pwdReset attribute is set to TRUE so that the user is forced to immediately change it on next login - which you have to enforce yourself by using the PasswordPolicy request control and inspecting any PasswordPolicyResponse for CHANGE_AFTER_RESET.
There's no particular reason why the admin should be constrained by the pwdHistory, and anyway the user is going to be forced to change the password again anyway, at which time he will be constrained by pwdHistory.

Related

How to check if signed in Firebase user has a Password

My app uses Firebase authentication with two providers(email/password and Google SignIn) but I require all my users to have a password so they can use any of these providers to sign in, now my problem is I want that each user that sign in using a provider different from email/password should be prompted to create a password immediately but I cannot find any method in the SDK to check if a user has a password.
I tried using the method below to check that but from my observation, this checks only for the provider the user used to Sign Up.
for(UserInfo info : currentUser.getProviderData()) {
if(!info.getProviderId().equals("password")) {
ShowUpdateUserPasswordDialog("CREATE",currentUser);
} else {
MoveToMainActivity();
}
break;
}
I require all my users to have a password so they can use any of these providers to sign in
Firebase authentication with email and password is a totally different authentication mechanism than the authentication with the Google provider.
now my problem is I want that each user that sign in using a provider different from email/password should be prompted to create a password immediately
If the user has chosen to sign-in with Google, why would you force him to enter a password? That's the whole idea, not to use a password anymore. Besides that, you let the user choose even from the beginning what kind of authentication to use. It's some kind of a bad user experience to force the user to choose one, or the other, or both.
However, if you still want to force the user the choose a password, you first need to sign-out the user from Google and Firebase so it can be signed in again with email and password. You can do that silently, but how about the situation in which the user wants to choose a password for the Gmail account that is already in use? In that situation you'll get an error, saying the account with that particular email already exists.
but I cannot find any method in the SDK to check if a user has a password
You didn't find something like that because something like that doesn't exist.
IMHO, some kind of operation might be considered bad practices and I cannot see any reason for doing that. You should let the user choose the type of authentication according to their own will.

Adding User in LDAP

I'm able to create the user in LDAP but its creating in disabled mode. When try to enable and give the password as Never Expire got this error. LDAP: error code 53 - 0000052D: SvcErr: DSID-031A11E5, problem 5003
This error code is very specific to Active Directory and indicates an "Unwilling to Perform". You can only set a password if the connection is secured by a certificate.
The hex value 0000052D of your diagnostic message relates to a system error code. Specifically:
ERROR_PASSWORD_RESTRICTION
1325 (0x52D)
Unable to update the password. The value provided for the new password
does not meet the length, complexity, or history requirements of the domain.
Either the password you are trying to set for the user account does not meet the password policy requirements or you are not encoding it properly (unicodePwd must be UTF-16LE).

Ldap password policy not throwing different errors

I use ppolicy overlay and enabled ppolicy_use_lockout to separate between invalid password and locked accounts.
database bdb
suffix "dc=openiam,dc=com"
rootdn "cn=Manager,dc=openiam,dc=com"
rootpw "{SSHA}2ttRoo/t5HuMT2nPxtI6goVUML5R2H9h"
# PPolicy Configuration
overlay ppolicy
ppolicy_default "cn=default,ou=policies,dc=openiam,dc=com"
ppolicy_use_lockout
ppolicy_hash_cleartext
I tried to lock user account by entering wrong password couple of times (pwdMaxFailure)
The user is being locked but when I try to login again I still get the same error:
Invalid credentials (49)
Any idea why i am not getting diffrent error to disticnt between the cases?
thanks,
ray.
you should add -e ppolicy when use ldapwhoami to get more information like (Password expired, 3 grace logins remain)
You will get a password policy response control that tells you the error, if you request it with the corresponding request control.
Note that it's a bad idea to let this show through to the user, for the reasons stated in the password policy draft, section 12. Basically you would be leaking information to an attacker.
Note also that this technique also applies to my answer to your previous question which I have now corrected.

Share Current User Data Between Subdomains on Google App Engine for Java

I am Using Google App Engine for Java and I want to be able to share session data between subdomains:
www.myapp.com
user1.myapp.com
user2.myapp.com
The reason I need this is that I need to be able to detect if the user was logged in on www.myapp.com when trying to access user1.myapp.com. I want to do this to give them admin abilities on their own subdomains as well as allow them to seamlessly switch between subdomains without having to login again.
I am willing to share all cookie data between the subdomains and this is possible using Tomcat as seen here: Share session data between 2 subdomains
Is this possible with App Engine in Java?
Update 1
I got a good tip that I could share information using a cookie with the domain set to ".myapp.com". This allows me to set something like the "current_user" to "4" and have access to that on all subdomains. Then my server code can be responsible for checking cookies if the user does not have an active session.
This still doesn't allow me to get access to the original session (which seems like it might not be possible).
My concern now is security. Should I allow a user to be authenticated purely on the fact that the cookie ("current_user" == user_id)? This seems very un-secure and I certainly hope I'm missing something.
Shared cookie is most optimal way for your case. But you cannot use it to share a session on appengine. Except the case when you have a 3rd party service to store sessions, like Redis deployed to Cloud Instances.
You also need to add some authentication to your cookie. In cryptography there is a special thing called Message Authentication Code (MAC), or most usually HMAC.
Basically you need to store user id + hash of this id and a secret key (known to both servers, but not to the user). So each time you could check if user have provided valid id, like:
String cookie = "6168165_4aee8fb290d94bf4ba382dc01873b5a6";
String[] pair = cookie.split('_');
assert pair.length == 2
String id = pair[0];
String sign = pair[1];
assert DigestUtils.md5Hex(id + "_mysecretkey").equals(sign);
Take a look also at TokenBasedRememberMeServices from Spring Security, you can use it as an example.

Session management between thick client and server?

My application is a Eclipse Rich Client and I would like to add authentication and authorization features to. My Users and roles are stored in a database and my application also has a web based admin console which lets me manage users and roles. I am leveraging Spring security on this admin console.
So here's my requirement:
I would like my thick client to provide users with a login dialog box. The authentication would need to be performed on the server side (it could be a webservice) and the roles have to flow in to the thick client. I would also like to manage sessions on the server side, somehow.
I really can't think of any easy way to doing this. I know that if I were to use Spring Rich Client, it would integrate pretty well with Spring Security on the server side.
But, that is not an option for me at this point.
Please share your thoughts on how to acheive this. Appreciate your help.
Since you're leaning toward web services (it sounds like you are) I'd think about taking the user information from your rich client (I assume user ID and password), using WS-Security to send the encrypted info to a web service, and having the web service do the auth stuff. Also I'd think about the web service returning any info that you want to go back to the rich client about the user (first/last name, etc).
I developed a similar application recently using the Challenge-Response-authentication. Basically you have three methods in your webservice or on your server
getChallenge(username) : challenge
getSession(username, response) : key
getData(username, action?) : data
getChallenge returns a value (some random value or a timestamp for instance) that the client hashes with his/hers password and sends back to getSession. The server stores the username and the challenge in a map for instance.
In getSession the server calculates the same hash and compares against the response from the client. If correct, a session key is generated, stored, and sent to the client encrypted with the users password. Now every call to getData could encrypt the data with the session key, and since the client is already validated in getSession, s/he doesn't have to "login" again.
The good thing about this is that the password is never sent in plain text, and if someone is listening, since the password is hashed with a random value, the call to getSession will be hard to fake (by replaying a call for instance). Since the key from getSession is sent encrypted with the users password, a perpetrator would have to know the password to decipher it. And last, you only have to validate a user once, since the call to getData would encipher the data with the users session key and then wouldn't have to "care" anymore.
I've a similar requirement I think. In our case:
user provides username and password at login
check this against a USER table (password not in plain text btw)
if valid, we want a session to last, say, 20 minutes; we don't want to check username and password every time the thick client does a retrieve-data or store-data (we could do that, and in fact it wouldn't be the end of the world, but it's an extra DB op that's unnecessary)
In our case we have many privileges to consider, not just a boolean "has or has not got access". What I am thinking of doing is generating a globally unique session token/key (e.g. a java.util.UUID) that the thick client retains in a local ThickClientSession object of some sort.
Every time the thick client initiates an operation, e.g. calls getLatestDataFromServer(), this session key gets passed to the server.
The app server (e.g. a Java webapp running under Tomcat) is essentially stateless, except for the record of this session key. If I log in at 10am, then the app server records the session key as being valid until 10:20am. If I request data at 10:05am, the session key validity extends to 10:25am. The various privilege levels accompanying the session are held in state as well. This could be done via a simple Map collection keyed on the UUID.
As to how to make these calls: I recommend Spring HTTP Invoker. It's great. You don't need a full blown Spring Rich Client infrastructure, it can be very readily integrated into any Java client technology; I'm using Swing to do so for example. This can be combined with SSL for security purposes.
Anyway that's roughly how I plan to tackle it. Hope this is of some use!
Perhaps this will help you out:
http://prajapatinilesh.wordpress.com/2009/01/14/manually-set-php-session-timeout-php-session/
Notice especially this (for forcing garbage collection):
ini_set(’session.gc_maxlifetime’,30);
ini_set(’session.gc_probability’,1);
ini_set(’session.gc_divisor’,1);
There is also another variable called session.cookie_lifetime which you may have to alter as well.
IIRC, there are at least 2, possibly more, variables that you have to set. I can't remember for the life of me what they were, but I do remember there was more than 1.

Categories