How to authenticate IdentityServer with firebase or Quickblox - asp.net

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?

Related

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

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/

Firebase admin - get Google OAuth token

I have a web application where users can sign in with Google.
To the sign-in process, I add a scope to be able to access Google Calendar.
Now that the user is signed in, I would like to - in server-side - get their current Google access token in order to make a request and get a list of their events.
Is there a way to get the current OAuth token (no need for refresh token) in order for me to make this completely on the server-side?
I'd say that you can check this article and put special attention to the recommendation for websites.
I understand you have configured already the consent screen, which is the first step of the basic steps on using OAuth 2.0. So I understand that you only have to perform the following steps:
Obtain an access token from the Google Authorization Server
Examine scopes of access granted by the user.
Send the access token to an API
I think you can also give a look to this other doc for more GCP insights over your goal to authorize the request using user tokens
Edited:
Regarding the Firebase Authentication, I understand this happens at the user's device, and you could use some code to retrieve the token and then send it to your back end servers as mentioned in here.
As a sample here there's the sample code for retrieving the token in Android:
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
.addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
public void onComplete(#NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
// Send token to your backend via HTTPS
// ...
} else {
// Handle error -> task.getException();
}
}
});
A little about OAuth 2.0
Whenever a user signs up to your app/website via Google or 3rd Party, an Authorization Code, this Authorization Code is exchanged for an AccessToken & RefreshToken.
The AccessToken sent via Google are valid generally for 60 minutes.
Offline Access (Server Side)
Let's break it down to two parts:
If your need to update within 60 minutes of user's last activity
You can use firebase along with gapi to achieve that. You'll be provided with the AccessToken that can be sent back to server to add to calendar.
More info on implementation
If you need to update after 60 minutes of user's last activity
Firebase & gapi's most method handle the AuthorizationCode flow internally. They even further refresh the AccessToken after 60 minutes. This is beneficial for most developers as they won't have a headache of managing all the tokens.
This method but, hides RefreshToken & AuthorizationCode from the developer. That is even if your server has the access token, it won't be able to refresh it and it would be deemed useless.
To achieve complete offline access, in the initial request to get AuthorizationCode you will need to send a HTTP GET parameter access_type to offline
GAPI provides you with grantOfflineAccess() method which returns the AuthorizationCode that can be later used on your server to fetch access token & refresh token.
Note: If you are storing AuthorizationCode in your database, make sure it is secure. The limitation in Firebase are set due to security reason. It is more secure to not talk with AuthorizationCode generally.
More links
https://developers.google.com/identity/protocols/oauth2/web-server
https://developers.google.com/identity/sign-in/web/reference
https://developers.google.com/identity/sign-in/web/server-side-flow
https://developers.google.com/identity/sign-in/web/backend-auth
Retrieve Google Access Token after authenticated using Firebase Authentication

How can I allow my Unity app access to a Firebase realtime Database without user accounts and without public access?

I am using the Firebase Unity SDK (5.4.3). I need the app to access a Realtime Database. Everything works fine when I have access configured to public, but I need to secure the database so it can only be read/modified through the app.
I followed the instructions here: https://firebase.google.com/docs/database/unity/start
for allowing the Editor to "configure the SDK to use a service account to run in the Unity Editor." This allows the Unity editor to access the database, but this does not work on device. There are instructions for authenticating users, but I do not want any sort of log in in the app.
In short, how can I allow access through the app but disallow access outside of the app. Can I use a service account on device and how do I configure that?
Thank you.
As said by Doug Stevenson it is not possible; you either have a public login or a restricted one with authentication.
However I would Simply have one dedicated user like myUnityAppUser with a password like e.g. 123456 somewhere defined in a script or maybe an additional encryption file somewhere.
Then do the login automatically without user interaction -> send userName+password. The password could still be encrypted etc but this can all be handled by the App itself without you actively doing the login Everytime
Than you make a usual login like e.g. (Source)
public void Login(string email, string password)
{
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SignInWithEmailAndPasswordAsync canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithEmailAndPasswordAsync error: " + task.Exception);
if (task.Exception.InnerExceptions.Count > 0)
UpdateErrorMessage(task.Exception.InnerExceptions[0].Message);
return;
}
FirebaseUser user = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
user.DisplayName, user.UserId);
SceneManager.LoadScene("LoginResults");
});
}
Now somewhere in your app you simply call
Login ("myUnityAppUset#some.email", "123456");
with the somehow somewhere "hardcoded" (maybe encrypted?) credentials.
Note that it is still possible that someone decompiles the app and can cheat again.
This is not possible. If you want to restrict who or what can access your Realtime Database (and Cloud Storage, and Firestore), you will need to use Firebase Authentication, and write security rules that lock down access to only users who have logged into your app/game.
Without Firebase Authentication in use, the only access to your database will essentially be public - by anyone who knows the name of your project. Anyone can find out the name of your project simply by reverse engineering your app/game and pulling the configuration information out of it. That configuration information is not private - it is also essentially public information.

Proper way to verify user's mobile number using Firebase

I know that I can use Firebase's phone verification on Android and iOS, but the problem is that the information about client's verification can easily be forged on the client side, because I using only server side SSL certificate, so, only client knows that the server is trusted.
So, I decided to send mobile number on the server-side and check it there: send verification code and ask this verification code from the user. But I can't see any C++ server Firebase SDK, only client-side C++ SDK is available.
So, I have two options:
Understand how is client-side verification can be trusted on the server-side(note that I can have untrusted clients)? So, it's means I could use main Firebase phone number auth method.
Use server-side phone verification.
Please, help me with this misunderstanding in the Firebase.
Client side absolutely works here. The flow is like this:
You request a sign in using a phone number
The Firebase Phone Auth server sends a code to that number
The user enters your code into your app, which sends it to the Firebase Auth server
The Firebase Auth server returns you a Firebase Auth token
This works because a malicious user could only know the code if they had your phone. It doesn't guarantee the device is the one with that phone number (the user could have two phones, or sign in with a phone on a laptop), but it does verify the user has access to that number.
For verifying that to your own backend, you retrieve a Firebase ID token. This is just a little bundle of base64 encoded JSON, but importantly its cryptographically signed by Firebase. This means on your server you can verify that it was really created by Firebase, for the user and phone number that is contained within it. A user couldn't generate one of those tokens without access to the underlying account.
See the docs on verifying ID tokens for more!
So your next steps would be:
Retrieve the Firebase ID token
You can do this any time you're signed in.
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getToken(true)
.addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
public void onComplete(#NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
// Send token to your backend via HTTPS
// ...
} else {
// Handle error -> task.getException();
}
}
});
Verify on server the contents of the ID token.
The admin SDKs are set up out of the box to check for the right certificate, audience, expiry, and other important properties of an ID token.
admin.auth().verifyIdToken(idToken)
.then(function(decodedToken) {
var uid = decodedToken.uid;
// ...
}).catch(function(error) {
// Handle error
});
decodedToken will contain properties for the phone number too!

Combining token based authentication with Windows Authentication

We currently have an internal API that uses Windows Authentication. I've been charged with looking into making this API public, and one of the requirements is that it should be possible to login without a domain user. Domain users should still be able to login, and should be considered super admins (access everything).
It is also clear that before long, we will need role or claim based authorization. As a prototype, I have implemented a system using ASP.NET Identity. Using JWT tokens and Claims based authorization.
But how do I ensure that users authenticated with Windows Authentication can skip the token step and simply use the API directly?
Found a solution where I add custom AuthorizationFilterAttributes to my endpoints. In the attribute, I check for the Principal type:
public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
if (actionContext.RequestContext.Principal is WindowsPrincipal)
{
return Task.FromResult<object>(null);
}
//Custom logic here
[...]
}

Resources