Firebase + Android + Spring to create microservices - android

Here is the idea:
There is an android application that will consume services that I will create using Spring. However, this services should have some sort of security, so only people logged in on my android app can consume such services.
On my android app, I will use Firebase to do the authentication, using email and password. So, there will be no need for me to configure any server to make this control. (Like Spring OAuth2)
The question is, once the user is logged on my app and wants to consume some service, for example GET LIST of something, that I will provide on the Server using Spring, how can I check if the user is logged on the app, so I can grant access to that service?

Your Android app will need to pass the user's token on to your app server, where you can then verify that the id token is valid and use the information in it.
See the Firebase documentation on verifying id tokens for full information, including this description:
If your Firebase client app communicates with a custom backend server, you might need to identify the currently signed-in user on that server. To do so securely, after a successful sign-in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.
Also note this first note in blue:
Note: Many use cases for verifying ID tokens on the server can be accomplished by using Security Rules for the Firebase Realtime Database and Firebase Storage. See if those solve your problem before verifying ID tokens yourself.
While it might not apply for your use-case, always keep it in mind since the most maintainable code is the code that you didn't have to write. :-)

Related

Handling Oath 2.0 Authorization from Backend Job

I am trying to find a solution to the following:
Requirments
There is exists an app that allows users to add integration providers
These integration providers use oath 2.0 authorization to secure their data
The app needs the ability to have a backend job fetch data on-behalf of the user once per day
The data fetched is ingested and merged into a report that is compiled on the app for the user
Problem
User Delegated Access Token from Backend Job - I'm having trouble finding the solution that allows me to have a valid access token that is on behalf of the user without having to generate the access token from the app side
What I have tried
Refresh Token - I have tried the approach of using the refresh token to constantly get a new access token but this solution is fragile in the sense that there might be a situation that a new token is not generated in time or for some reason the user still needs to reauthenticate the connection to the provider
Automated Browser Flows - I have tried automating the user's authentication flow from the backend using saved credentials given in the app. This approach is just sketchy, costly, and would require a lot of work on the user agreement side ensuring that is being done on the backend has been consented by the user which essentially reinvents the wheel on user consent which the identity providers should have already been handling
We can use JWT for this. By doing it with JWT we'll create a token and save to the database and on every request it will decrypt the token and get the required data from the token.
Link- https://jwt.io/

Verify ID Tokens: What is the workflow to use this Firebase checkment?

Some months ago, Doug Stevenson told me to use the Firebase checkment dedicated to the "ID Tokens verification": https://firebase.google.com/docs/auth/admin/verify-id-tokens
I have read the doc. What I have understood is: I can't trust the Android app when it announces to the server (Firebase Firestore Rules, Firebase Firestorage Rules, Cloud Functions) the ID of the user, because it can take an existing ID other than its actual own ID and announce it. So I have to use the token system proposed in the doc.
What I have understood too is: I must get the token just after the user successfully has logged in. Then I send it to the server and it "checks it". But then... what? Okay, the server checks it. But the result of this check, what should the server do with it?
Should I do all of this (send the token to the server, check it server-side, do something server-side with the result of this check) before each call made by the Android app to the server?
Examples:
if my Android user wants to edit its account, he will fill in the form (firstname, age, bank code, picture avatar). This data will be sent to Firestore and Firestorage, so their Rules will be executed ; the UID of the user must be passed, but in fact it should be the token, no? (since the Android app can lie on the UID by sending a fake UID if it's a hacker, cf. the beginning of this SO Question).
if my Android app sends data to Cloud Functions, that treats it and itself saves it into Firestore and Firestorage, should I use the token system too?
When writing directly to Firestore or Cloud Storage, the user can't fake sending a UID other than their own. As long as your security rules check it correctly, you won't have a problem. There are examples of how this works in the documentation. There is no need to verify any ID tokens when using security rules to control access - this is all handled automatically.
You use the Firebase Admin SDK to verify a token in the where your client app is directly invoking an HTTP type function, and that function needs to make sure that only valid users are allow to execute the code. The client sends the user's token along with the request, as shown in the documentation you linked, and the code on the backend should verify the token before doing any work on behalf of the user. There is really no need to try to pass along an ID token in any other type of Cloud Function.

How can I secure the cloud database for my mobile app?

I'm working on a mobile app that has both local database and AWS RDS. Data needs to be passed both ways so that user data can be backed up and updated data can be sent to the app. I set up an API to avoid putting database credentials in the app itself. The API triggers code hosted in the cloud to interact with the RDS.
As I understand, Android APK files can be easily hacked. I would like a solution for how to prevent someone from reverse engineering the app's API calls and getting private user data from the RDS. As it is currently, if someone knows how to format an API call they could access data belonging to any user.
You need an API Authorization mechanism. Normally APIs are protected with Authorization Token which is obtained by a successful login. When the user successfully logs in, you should issue the authorization token, Store in device shared preferences that need to be passed with further API calls. I suggest using JWT, simple and available in all major programming languages. Encode the user's unique identifier in JWT token and design your API such a way that the user can only create, read, update, delete based on the identity encoded in JWT. By this, suppose if user token is compromised, that token can be only used to misuse the user-specific data and not all the data in your database.
Consider the given flow for your reference.

How can I securely store user credentials for my app

I have an Android app that allows users to interact with a third-party service via their API. This API makes use of Basic Authentication, so I need the user's username and password for every API call. Ideally I don't want to store the user's credentials locally as this is very insecure. I don't know much about authentication but this is what I think my ideal solution would be:
The user provides their credentials to this service once for verification
Once verified, I send the user's credentials to a backend service to store them, which gives me an auth token. I store this token locally (is encryption important here?)
Whenever I want to make future calls to this service, I use this auth token to talk to the backend service, which provides me with the user's username/password for Basic Authentication to make API calls
Is this a good solution? If so, are there backend services in place that I can use to facilitate this process? I've looked at Firebase Authentication but I don't know if it fills my needs as I'm trying to store credentials for a third-party service, not specifically for my app. I've heard of Auth0 which may be what I'm looking for but appears to be overkill for a small app like mine.
You can easily use Firebase Auth and get all the functionality you need while keeping your users secure. It provides the features you need:
Firebase supports password authentication and properly stores hashed/salted password credentials according the industry standards. This would be one API to createUserWithEmailAndPassword or signInWithEmailAndPassword.
Firebase provides a mechanism to verify email addresses. It is also one API: user.sendEmailVerification()
On sign in, Firebase Auth returns an ID token (user.getIdToken()) which you can use to identify your users in all authenticated requests. They also provide an Admin SDK to parse and verify that token (auth.verifyIdToken(idToken)). A refresh token is also provided to continuously refresh ID tokens on expiration. This means the sessions are indefinite and the user should not need to sign in again on the device.
The ID token provides additional user data like email_verified which you can use to ensure the user is verified. The ID token is a JWT which can't be compromised without the Firebase Auth backend private key.

Android Google+ Session

I'm using Google+ authentication in my app to allow a user to sign in, and have access to their 'data' on my server.
The authentication process following the following steps:
User logs in using Google+ on the app, and receives an access token.
The user passes this token to the server.
The server uses this token to verify that the user is who they say they are (following the process shown here). The server can return the data as needed.
This is the part I'm stuck on - How do I verify that the user is who they say they are for future requests without making a request to Google's servers every time? Do I return a session token to the client application that is used, and regenerate the token after some amount of time?
Absolutely. Sending a session cookie is exactly the thing to do.
You will want to use ID tokens to verify that the user is who they say they are. There is a sample project in Java on Github to demonstrate this.
Also, you should be passing a one-time authorization code to your server, not access tokens. See the documentation for getting your server side tokens from an Android app. When you have that code, you send that to your backend and then exchange that one-time code for the server's own copies of access and refresh tokens for that user. Because you receive the tokens directly from Google on your backend they are more secure than having to send between mobile apps and your backend.

Categories

Resources