Re-authenticate a user. with FirebaseUI auth for Android - java

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.

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.

Login Design Logic

This is a pretty generic question, but any advice is appreciated.
I am writing an Ionic2 app that uses Firebase Authentication.
A user can sign up to the app. A verification email is sent to the user's email address. If the user verifies their email, they can access the app.
However, if a user does not verify their email, for example if they signed in with the incorrect email address, then the email will never be verified. In such a case, the incorrectly registered email address sits on the Firebase database redundantly, or if the valid user tries to signup with that email, they get a message that that email address belongs to the original provider (Facebook, Google or plain email), and cannot sign up as a different provider.
As you can see, the above situation can potentially block a user from registering their email address.
I have tried to delete the Firebase account when the user comes to sign in so they start afresh as I do have the matching uid. However, I don't think the AngularFire2 api allows a Firebase account to be deleted by uid. See here.
Can either suggest:
How to delete the account by uid, or
Another design I can use to resolve this issue.
Thanks you
UPDATE
Thank you for the advise below. I have a Java server which I would like to do the Firebase Admin management of users.
I have found Java documentation on how to initialize Firebase Admin. e.g.
public void initialize() {
String keyPath = "/appname-123456-firebase-adminsdk-eknji-3071d579f5.json";
InputStream serviceAccount;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
serviceAccount = loader.getResourceAsStream(keyPath);
// serviceAccount = new FileInputStream(keyPath);
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
.setDatabaseUrl("https://appname-123456.firebaseio.com").build();
FirebaseApp app = FirebaseApp.initializeApp(options);
FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseDatabase database = FirebaseDatabase.getInstance();
}
I can find Node.js documentation on how to manage users. But how do you do this in Java? i.e. How do I delete a user by uid?
UPDATE
Looks like you need to create a custom token with the uid. See here.
How do you do the following in Java?
admin.auth().deleteUser(uid)
.then(function() {
console.log("Successfully deleted user");
})
.catch(function(error) {
console.log("Error deleting user:", error);
});
UPDATE
I don't think it is possible to manage accounts in Java. I think the custom token needs to be passed back to the client, and then used to sign in for that user. see here.
There are three ways to delete a Firebase Authentication account:
from the Firebase Authentication console.
by calling delete() on the signed in user from the app.
by calling deleteUser() from the Admin SDK.
It sounds like you're looking for option 3. This requires that you run a trusted process that deletes the extraneous users. Don't try to run this code in your actual app, since that would open up a security that allows all your app's users to delete each other's account.

GWT RequestFactory-based authentication

I am experimenting with GWT RequestFactory (RF) for the first time and am trying to implement a simple sign-in screen and authentication system (not using anything fancy, just fiddling around with the basics here). The basic user experience I'm looking to achieve is pretty par for the course:
The user will be presented with a sign-in screen (email and password and "Sign In" button). When they click the button, I want to use RF to send their credentials to the server (using ValueProxy since these are not entities) and authenticate them. If the credentials were correct, they are now "signed in" to the system, and the GWT app will download a whole new module and they'll be redirected to their account's main menu. If the credentials were incorrect, I want to send back a String explaining that the email or password was incorrect, and they are still "signed out" of the app.
Regarding this question that I posted yesterday, I have now figured out how to use RF to expose a SignInOutService which has a signIn(SignIn) method for attempting to sign the user in, and a signOut(SignOut) method for signing the user out of the system. But now I'm actuallly trying to implement that service, and here's what I have so far:
public class DefaultSignInOutService {
// Try to sign the user into the system.
public String signIn(SignIn signIn) {
// The SignIn object contains the email/hashed password the user tried
// signing-in with, as well as other metadata I'm looking to store for
// security purposes (IP address, user agent, etc.).
String email = signIn.getEmail();
String hashedPassword = signIn.getHashedPassword();
// This will be set to a non-null value if the sign-in attempt fails.
// Otherwise (on successful sign-in) it will stay NULL. The client-side
// handler will know what to do with the UI based on this value.
String failReason = null;
// For this simple example, the password is "12345" and below is it's MD5 hash.
// Hey! That's the combination on my luggage!
if(!"skroob#spaceballs.example.com".equals(email) || !"827ccb0eea8a706c4c34a16891f84e7b".equals(hashedPassword))
failReason = "Login failed; incorrect email or password.";
else {
// Log the user into the system...
// TODO: How?
}
return failReason;
}
// Sign the user out of the system.
public void signOut(SignOut signOut) {
// The SignOut object should reference the user attempting to sign out, as well as a reason
// for why the sign out is occurring: the user manually requested to be signed out, or they
// "expired" due to inactivity or navigating the browser away from the app, and so the system
// auto-signed them out, etc.
// TODO: How?
return;
}
}
So now, I've implemented my super-simple email/password check, and I'm ready to write the code that somehow signs the user into the app (so that they're not presented with a login screen over and over again). And I'm choking on what to do next.
Issues I'm trying to find solutions for:
Is GWT RF somehow session- or token-based? If so, under the commented line "Log the user into the system...", what code can I write that says "this user is now authenticated, set some cookie or session variable to make it so!"? I ask this because once they sign in and are routed to the new module and main menu, GWT will need a way to authenticate every subsequent RF request thereafter.
What does the signOut() method need to reset/clear/nullify in order to clear these cookies/session vars? In other words, how do I actually sign the user out, so if they try to go to the URL for their main menu (which again is only accessible if they're signed in), they'll be redirected to the sign-in screen?
How could I implement a 15-min inactivity timeout, where the user is automatically signed out of the app after a certain length of time? I think this answer will become more obvious once I see how questions #1 and #2 above work.
I was told that I may need to have two servlets and/or filters: one for handling unauthenticated RF requests (while a user is signed out or has not yet signed in), and one for handling authenticated RF requests (once the user is actively signed in). But I can't see how they fit into the overall picture here.
The easiest way is to store your authentication details in session.
public String signIn(SignIn signIn) {
...
if(!"skroob#spaceballs.example.com".equals(email) || !"827ccb0eea8a706c4c34a16891f84e7b".equals(hashedPassword))
failReason = "Login failed; incorrect email or password.";
else {
RequestFactoryServlet.getThreadLocalRequest().getSession().setAttribute("auth", signIn);
}
return failReason;
}
public void signOut(SignOut signOut) {
RequestFactoryServlet.getThreadLocalRequest().getSession().removeAttribute("auth");
return;
}
On every request you can check if SignIn object is still present in session:
SignIn signIn = null;
final Object userObject = RequestFactoryServlet.getThreadLocalRequest().getSession().getAttribute("auth");
if (userObject != null && userObject instanceof SignIn) {
signIn = (SignIn) userObject;
}
In case of absence of this object you should cancel the request and redirect user to login page.

how to implement the create new password functionality directly from user's email

I am trying to implement the scenario in which a new user has been created in my application by Admin.
1st step will be
user has allotted by a temporary password
and receives the email with an activation link
User will just by clicking on that link taken to the create new password page , he creates his new password and thats it.
Now my query is how will the application knows that which user is this ,just by clicking that activation link in his email
Activation links carry a long token, such as activate.jsp?tok=98357627272357852786276258763427934579342579342793426734279. This token can be randomly selected, and stored in a database. When the page is loaded, the token is looked up, and the correct user gets authenticated. The token may then be deleted from the database.

Creating muti user access login form

I have created a login form for a system which i have created. Currently i have only one user access login meaning only one login for the whole system.
Here is what i want to do , i want to have multiple user logins such as for a doctor , nurse , admin . There should be restrictions as well, such as if the user is logged in as a doctor or nurse, the user can only view their details and where else if the user has logged in as admin , then the user can access any part in the system.
Here is what i have done so far:-
private void btnenterActionPerformed(java.awt.event.ActionEvent evt) {
String password=new String (txtpassword.getPassword()); //method to get the password from password field
String username=txtusername.getText();
if(username.equals("admin") && password.equals("admin123"))
{
JOptionPane.showMessageDialog(frame,"Welcome to the System","WELCOME",JOptionPane.INFORMATION_MESSAGE);
Main_menu enter=new Main_menu();
enter.setVisible(true);
close();
}
else
{
JOptionPane.showMessageDialog(frame,"Wrong username/password","Invalid username or password",JOptionPane.ERROR_MESSAGE);
}
}
I can use this same method to give different access logins but i cannot set an access level to an user, except by going to each and every form in the system and using "if" condition and restricting the user access level.
But this isn't very effective enough for me, so is there any other method to do this in a simpler way ?
Thank you for your time
I believe that normally you would create an authentication function, and then you would simply call that anywhere where the user needed to authenticate. Alternately, it's fairly common to group all of the restricted functions into a set of restricted pages, and call the authentication when the page is loaded, so that you don't have to verify it on each and every form. One of the common methods is through cookies. When the user logs in, you set a cookie for them. The restricted pages call a check to make sure the user has that cookie, and if they don't, they get redirected to the login page.
I'm not a Java developer so I couldn't tell you what the code for that would be, but I believe that's the standard MO in PHP, and I do know many sites like to set cookies with Javascript (much to my dismay).

Categories