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.
Related
I'm using Firebase-UI auth and I want to implement delete account functionality for my application.
Some security-sensitive actions—such as deleting an account, setting a primary email address, and changing a password—require that the user has recently signed in.
To delete a user, the user must have signed in recently, See Re-authenticate a user.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential(user.getEmail(), );//how can i get password of the user
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "User re-authenticated.");
}
});
is there any way to get the current password from the user or any other solution?
I search all the documentation and I can't find a method that gives me the current password of the user.
Some security-sensitive actions—such as deleting an account, setting a primary email address, and changing a password—require that the user has recently signed in.
Yes, that's correct. As soon as 5 minutes have passed since the last log-in, the delete account operation cannot be performed, as it is considered a sensitive operation.
Is there any way to get the current password from the user or any other solution?
No, there is no way you can get the password of the logged-in user. Nobody will ever provide that. When a user tries to delete the account when 5 minutes have already passed since the last log-in, then you have two options available:
You provide in the UI the possibility to sign out. In this way, the user will be redirected to a sign-in screen. As soon as it lands on the sign-in screen the user will be able to restart the authentication process.
You can keep the user logged in but you'll need to provide an option to type the password again. As soon as you have the password, then you can call FirebaseUser#getEmail() to get the email of the logged-in user. Right after that, you can call EmailAuthProvider#getCredential(String email, String password) to get an object of type AuthCredential. Having such an object, you can call then call FirebaseUser#reauthenticate(AuthCredential credential) to reauthenticate with its own credentials.
No matter what option you choose, right after a successful authentication or a successful reauthentication, the user will be able to delete the account in a 5 minutes time frame.
Personally, I prefer the first option as it needs only a sign-out option. But it's up to you to decide which is better for your use case. In code, it looks like this.
After a user creates an account, is he/she already signed in after createUserWithEmailAndPassword() returns successful? Or right after the account creation I need to then sign the user in with signInWithEmailAndPassword()?
After creating the account, the user is automatically signed in. See the section at https://firebase.google.com/docs/auth/android/password-auth
This is assuming the account creation was successful. You can check by using:
mAuth.getCurrentUser() != null
I'am developing Api's for Reset Password :-
1st One :- validating email or phone and Send OTP.
2nd One :- validating OTP.
3rd One :- Reset Password.
Problems:-
1.How I can maintain OTP at api side to validate it.
2.If a person directly hit my reset password Api,then he/she could change password, which is a security breach.
Please answer!!!Thanx in advance
1.How I can maintain OTP at api side to validate it.
OTP for password reset should be random, time limited and bound to a username. So yes, you need to maintain the OTPs persistently
Option one - you either build a database where you store the generated OTPs with their validity.
Option two - you can generate OTP in form of signed jwt so the validation algorithm just validates the timestamp and signature (this OTP password is longer, so feasible only for email)
2.If a person directly hit my reset password Api,then he/she could change password, which is a security breach.
There is no point of exposing a separate validation service. The reset service itself should validate the otp and reset the password or not (as one operation)
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.
I am obtaining a kerberos ticket with the following code:
String client = "com.sun.security.jgss.krb5.initiate";
LoginContext lc = new LoginContext(client, new CallbackHandler() {
#Override
public void handle(Callback[] arg0) throws IOException, UnsupportedCallbackException {
System.out.println("CB: " + arg0);
}
});
lc.login();
System.out.println("SUBJ: " + lc.getSubject());
This code works fine, I get a subject that shows my user ID. The problem I'm having is now I need to know whether the user belongs to a certain group in AD. Is there a way to do this from here?
I've seen code to get user groups using LDAP but it requires logging in with a user/password, I need to do it the SSO way.
You cannot actually do this with the kind of ticket you get at login. The problem is that the Windows PAC (which contains the group membership information) is in the encrypted part of the ticket. Only the domain controller knows how to decrypt that initial ticket.
It is possible to do with a service ticket.
So, you could set up a keytab, use jgss to authenticate to yourself and then decrypt the ticket, find the PAC, decode the PAC and then process the SIDs. I wasn't able to find code for most of that in Java, although it is available in C. Take a look at this for how to decrypt the ticket.
Now, at this point you're talking about writing or finding an NDR decoder, reading all the specs about how the PAC and sids are put together, or porting the C code to Java.
My recommendation would be to take a different approach.
Instead, use Kerberos to sign into LDAP. Find an LDAP library that supports Java SASL and you should be able to use a Kerberos ticket to log in.
If your application wants to know the groups the user belongs to in order to populate menus and stuff like that, you can just log in as the user.
However, if you're going to decide what access the user has, don't log in as the user to gain access to LDAP. The problem is that with Kerberos, an attacker can cooperate with the user to impersonate the entire infrastructure to your application unless you confirm that your ticket comes from the infrastructure.
That is, because the user knows their password, and because that's the only secret your application knows about, the user can cooperate with someone to pretend to be the LDAP server and claim to have any access they want.
Instead, your application should have its own account to use when accessing LDAP. If you do that, you can just look up the group list.
I do realize this is all kind of complex.