How to bypass the standard Mesibo login and use AWS Cognito instead - mesibo

I am using the Mesibo messenger/chat app. I have my own custom login that uses AWS Cognito. The Mesibo messenger app requires a phone number login. I want to totally bypass their authentication and use my own. I simply need to know how to turn off this authentication (the user will already be authenticated in my app). I'd like the user to authenticated with Cognito, they click a button/onClick listener and flow directly to the chat app without a 2nd login for Mesibo. I also have a cognito federated token I can pass. Anyone have an code examples?
My auth method currently lands on the activity I am granting access to:
{
Amplify.Auth.fetchAuthSession(onSuccess -> {
AuthUser user = Amplify.Auth.getCurrentUser();
if (user != null) {
Log.i(TAG, "MainActivity, signed in, current user: " + user.getUsername());
goAuthenticatedActivity(null);
} else {
Log.i(TAG, "MainActivity, signed in, user name is null");
}
}, onError -> {
Log.i(TAG, "MainActivity, signed in, error getting user session: " + onError.toString());
});
}
public void goAuthenticatedActivity(View view) {
Log.i(TAG, "in goAuthenticatedActivity()....going to AuthenticatedUsersActivity...");
Intent intentAuthenticatedActivity = new Intent(this, MesiboChatActivity.class);
startActivity(intentAuthenticatedActivity);
}

This is from mesibo documentation https://mesibo.com/documentation/tutorials/get-started/auth/
Note that mesibo does not recommend or enforce any particular
authentication method. You can use any authentication mechanism
suitable to your app, for example, email, phone, user-id, LDAP,
RADIUS, OAuth2, Kerberos, SAML, fingerprint, etc. All you need to do
is to generate a mesibo access token only after your user passed your
authentication.
the messenger app essentially handles login, contact synchronization and then launches mesibo messaging or call modules. If your users are already authenticated, you really don't need to use messenger. Instead, generate a mesibo access token for each of your users and directly launch respective UI modules.
https://mesibo.com/documentation/tutorials/get-started/

Related

Firebase auth overriding user providers (email + password, phone) when signing-in with Google

As we have seen in another posts related to this situation and github issues, the expected behavior is that Google IDP overrides other non trusted providers related to the same email as an example, another account with the same email + password (non-verified).
Trying to understand Firebase Authentication one account per email address and trusted providers
Firebase Overwrites Signin with Google Account
https://github.com/firebase/firebase-ios-sdk/issues/5344
https://groups.google.com/g/firebase-talk/c/ms_NVQem_Cw/m/8g7BFk1IAAAJ
So, ok, according to google that's the expected behavior.
Our questions comes when we go to the documentation and there's an example of a user login in with google and getting this error auth/account-exists-with-different-credential just because there's another account created with email+password with the same email. Then, they recommend to catch the error, check the user email related login methods and ask the user to login with the other provider and then link to google.
Does this make sense ? If they say the expected behavior is that google as a trusted provider will override the others (this is what happens to us) how is possible that the case of the code example would even occur ?
https://firebase.google.com/docs/auth/web/google-signin#expandable-1
// Step 1.
// User tries to sign in to Google.
auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()).catch(function(error) {
// An error happened.
if (error.code === 'auth/account-exists-with-different-credential') {
// Step 2.
// User's email already exists.
// The pending Google credential.
var pendingCred = error.credential;
// The provider account's email address.
var email = error.email;
// Get sign-in methods for this email.
auth.fetchSignInMethodsForEmail(email).then(function(methods) {
// Step 3.
// If the user has several sign-in methods,
// the first method in the list will be the "recommended" method to use.
if (methods[0] === 'password') {
// Asks the user their password.
// In real scenario, you should handle this asynchronously.
var password = promptUserForPassword(); // TODO: implement promptUserForPassword.
auth.signInWithEmailAndPassword(email, password).then(function(result) {
// Step 4a.
return result.user.linkWithCredential(pendingCred);
}).then(function() {
// Google account successfully linked to the existing Firebase user.
goToApp();
});
return;
}
// All the other cases are external providers.
// Construct provider object for that provider.
// TODO: implement getProviderForProviderId.
var provider = getProviderForProviderId(methods[0]);
// At this point, you should let the user know that they already have an account
// but with a different provider, and let them validate the fact they want to
// sign in with this provider.
// Sign in to provider. Note: browsers usually block popup triggered asynchronously,
// so in real scenario you should ask the user to click on a "continue" button
// that will trigger the signInWithPopup.
auth.signInWithPopup(provider).then(function(result) {
// Remember that the user may have signed in with an account that has a different email
// address than the first one. This can happen as Firebase doesn't control the provider's
// sign in flow and the user is free to login using whichever account they own.
// Step 4b.
// Link to Google credential.
// As we have access to the pending credential, we can directly call the link method.
result.user.linkAndRetrieveDataWithCredential(pendingCred).then(function(usercred) {
// Google account successfully linked to the existing Firebase user.
goToApp();
});
});
});
}
});
There's another example with the same structure in the flutter docs:
https://firebase.google.com/docs/auth/flutter/errors#handling_account-exists-with-different-credential_errors
Is this a contradiction in the documentation ? Again, if Firebase will always give priority to the trusted IDP (Google email) in this case, how is it possible to get this error if the other provider will be deleted (at least when having account linking activated - single account per email activated)
At least this is our case. We create an account with email & password and then try to login with google with the same email and what happens is that the email&password account is overwritten by the new google provider.
Unfortunately, you can't change it. If a user with #gmail.com email and password authentication updates their profile picture and then later logins with Google then the profile picture and any other information will be overwritten with the data from Google. The only option is to create a user record in the database that gets populated with the user data (displayName, photoURL etc) when the user is created for the first time. You then always use the data from this record instead of the default user object that is returned by the authentication.
The other advantage of creating a record is that you can attach a listener to it. That way if the user changes their details then it gets reflected everywhere.

Firebase email/password authentication - how to require email verification?

Whenever I use the email/password authentication provider in Firebase, the provider sends a bearer token upon successful sign-up even though the emailVerified is false. Is there a way, out of the box, to configure the email/password auth provider to not send a bearer token (and return a 403 error) until the user has verified their email address?
Note that I'm aware of how to create a user, sign in a user, send a verification email, etc... using firebase v9.x via the methods createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, sendEmailVerification from firebase/auth. I'm just asking if there is a way to set the behavior of the provider without having to write my own handler function for this. I'd like this to behave like Cognito does whenever the email verification is required.
There is no way to require the user's email address to be verified before they can sign in to Firebase Authentication.
The closest you can get is by using email-link sign-in, which combines signing in and verifying the user's email address in one action.
But this is how you'll typically want to implement this in your application code:
User enters their credentials
You sign them in to Firebase with those credentials
You check whether their email address is verified
If not, you stop them from further using the app - and (optionally) send them a verification email.
Same with data access: if you have a custom backend code, you can check whether the email address is verified in the ID token there too, as well as in Firebase's server-side security rules.
As per the documentation, you can use blocking functions to require email verification for registration (only that it doesn't work):
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
const locale = context.locale;
if (user.email && !user.emailVerified) {
// Send custom email verification on sign-up.
return admin.auth().generateEmailVerificationLink(user.email).then((link) => {
return sendCustomVerificationEmail(user.email, link, locale);
});
}
});
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
if (user.email && !user.emailVerified) {
throw new functions.auth.HttpsError(
'invalid-argument', `"${user.email}" needs to be verified before access is granted.`);
}
});
generateEmailVerificationLink always returns the following error:
"err": {
"message": "There is no user record corresponding to the provided identifier.",
"code": "auth/user-not-found"
},
but the user is created anyway given that beforeCreate don't return an exception.
If you want to check by yourself just log the error:
return admin.auth().generateEmailVerificationLink(user.email)
.then((link) => {
functions.logger.info("link", {user: user, context: context, link: link})
})
.catch((err) => {
functions.logger.info("error", {user: user, context: context, err: err});
});
The createUserWithEmailAndPassword() will sign in user right after the account is created. Also there isn't any way to prevent users from logging in even if their email is not verified but you can actually check if email is verified in security rules or using Admin SDK to prevent users with unverified email from accessing your resources. You can use this rule in Firestore:
allow read, write: if request.auth.token.email_verified == true;
One workaround would be creating users using a Cloud function and Admin SDK which won't sign in users but do note that users can sign in.
If you want to prevent login unless the email is verified strictly, then you can disable account right after it is created. Now you may not be able to use sendEmailVerification() which requires user to be signed in at first place, you can always create your own solution for verifying email. The process might look something like:
Create a user and disable the account in a Cloud function
Generate some token or identifier for verifying email and send an email to user from same cloud function
Once the user visits that link and verifies the email you can enable it
Additionally, users can still create accounts by using REST API but you can disable sign ups so users can be created via Cloud function only which disables the user immediately.

Firebase Auth verify this user

I am currently verifying my user using the Auth JS SDK and Admin Auth SDK combined. I am doing in the following approach:
In the front-end:
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
var current_user = firebase.auth().currentUser;
current_user.getIdToken(true).then(function (idToken) {
$.getJSON('/firebase_token', { token: idToken }, function (user) {
In the back-end:
router.get("/firebase_token", (req, res, next) => {
admin.auth().verifyIdToken(req.query.token).then(function(decodedToken) {
res.send(decodedToken);
})
})
I am wondering if this is a secured approach, because the user can just send whatever token they want from the front-end. For example, an invalid user can send a valid token they copied from a valid account to pass the token verification.
I am wondering if in the admin SDK. There is a way to detect the currently signed in user. In other words, detect this user who is using this instance of the app with the admin SDK?
I am wondering if this is a secured approach, because the user can just send whatever token they want from the front-end. For example, an invalid user can send a valid token they copied from a valid account to pass the token verification.
Yes, that's possible. But then again, if the user got access to a token, that means they probably are the user represented by that token, or they know the credentials of that account. That's not a problem at all - this is the way authentication systems work.
I am wondering if in the admin SDK. There is a way to detect the currently signed in user. In other words, detect this user who is using this instance of the app with the admin SDK?
No, the Admin SDK can't possibly know what all is going on for all of the users using your application. The ID token is exactly the piece of information it needs to verify users. A valid token proves that the user is who they say they are.

How to authenticate IdentityServer with firebase or Quickblox

I design a mobile application (Android for now) which depend on large ecosystem.
One of my main components is Auth system and I built it using IdentityServer3.
Now For user to login via the mobile application I use the OAuth2 implicit flow, so I opened a server side web page which take and validate user credentials, then generate id_token and access_token so I have no idea about the user password as client side.
Now, I want to implement another feature which is real-time chatting between users.
I checked a lot of solutions but everyone has a security weakness which may lead in the feature to an unwanted scenarios.
For Example:
QuickBlox:
QuickBlox clouding service (I don't know about the enterprise on-primes one) required to create a user then login with the user to create session using username and password.
QBAuth.createSession(new QBUser("user", "pass"), new QBEntityCallback<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
// success
}
#Override
public void onError(QBResponseException error) {
// errors
}
});
So it has its own UserStore which is separate from my central Auth service, so I thought about creating a dummy password with a layer of security like creating a well defined password consist of
UserName#ServerSideSecretKey
But this is not the way that I should go on as I should depend on my Central Auth service and only generate token, then pass it to QuickBlox to identify my user through my Auth UserInfo endpoint.
Is it something like this which allow me integrate QuickBlox with my Auth service??
I found this line in the documentation:
It's also possible to initialize the SDK with an existent QuickBlox
token. It can be interesting in cases when you build a big system and
you have a custom server side which generates QuickBlox tokens:
try {
QBAuth.createFromExistentToken("31ed199120fb998dc472aea785a1825809ad5c04", date);
} catch (BaseServiceException e) {
e.printStackTrace();
}
but I don't understand how this will work or how to allow QuickBlox validate my generated OAuth2 token.
Firebase:
In Firebase, I know that I can generate JWT tokens, then validate it against my firebase service so I should change my IdentityServer token generation behaviour to be JWT and then validate it against the Firebase secret key that I applied?
So how can I do that in identity server with implicit flow? Or is there another solutions?

Facebook Javascript SDK - How to tie with ASP.NET MVC Login?

I have an ASP.NET MVC4 web application, and I would like to use Facebook to authenticate users.
My plan is to have users "Sign Up" with Facebook, and then login using it.
Now this is fine when a user comes to the site and logs in with the Facebook Login button I have setup, which goes through an /Account/FacebookLogin action. In that action I can grab the Auth Token and check it against an SQL database to then authenticate the user with all the extra fields/info I store about them in my database (It's a web based game so Character name etc)...
Now, if the user comes to my site and they are already logged into Facebook, they obviously don't go through that /Account/FacebookLogin action... I simply have access to the auth token through the
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
var accessToken = response.authResponse.accessToken;
//alert("User is logged in");
}
else if (response.status === 'not_authorized') {
//alert("User is not authorised");
}
else {
//alert("User is not connected to Facebook");
}
});
My question is... What can I do in the "if connected" code to authorize my user, without sending them into an infinite loop? I tried redirecting them to the /Account/FacebookLogin action and passing in the auth token etc. But the getLoginStatus callback is called on every page... so they get stuck in an infinite loop..
Facebook has given you access to someone's Facebook identity. You might now want to create a user account for that identity. Once that user has an account then you then need to get the user to authenticate themselves with your application (you can use the Facebook identity to do this if you wish to tie yourself to Facebook). You can then authorize that user to undertake certain actions within your application.
In the context of MVC, you could quite simply issue them with a forms authentication token:
var username = response.authResponse.name; // <- check the syntax on this
FormsAuthentication.SetAuthCookie(username, true);
return this.RedirectToAction("Index", "AuthorizedUsersOnlyController");

Resources