Firebase realtime database emulator ignoring rules when access_token is set in REST query? - firebase-realtime-database

Every queries (at least from the REST API) seems handled like admin query when access_token is set (even with a dummy value), ignoring any rule:
{
"rules": {
".write": false,
".read": false
}
}
i database: Change detected, updating rules for my-project-default-rtdb...
+ database: Rules updated.
POST http://localhost:9000/test.json?ns=my-project-default-rtdb=>401 Unauthorized
POST http://localhost:9000/test.json?ns=my-project-default-rtdb&access_token=foo=>200 OK
Rules appear loaded at http://localhost:9000/.inspect/coverage?ns=my-project-default-rtdb
no user are created with Firebase Auth, the token is just "foo".
Is there a settings to enable proper auth support for the Realtime Database emulator?

If you authenticate a rest to the REST API to the production Realtime Database with an access_token, the user is a collaborator on the Firebase project (or it's a service account) and has full access to the database. This type of access does not have to abide by the security rules of the database, similar to how such a collaborator can access all data in the Firebase console. From the documentation:
Google OAuth2 access tokens - Typically, the ability to read from and write to the Realtime Database is governed by Realtime Database Rules. But, you can access your data from a server and grant that server full read and write access to your data with a Google OAuth2 access token generated from a service account.
It sounds like the emulator may not be actually validating the token, but the logic seems the same: using access_token grants access to the entire database, bypassing the security rules.
This also explains why you don't see the user in Firebase Authentication: this type of access does not use Firebase Authentication at all, and is intended for use with collaborators on the project and service accounts.
If you want to access the database as a regular user, authenticate with an ID token in the auth parameter instead.

Related

how can I generate a Keycloak user access token without password?

I have a legacy system that has an existing login mechanism - assume it is a custom method. We have another set of services that require an oauth2 access token and use keycloak for generating and verifying the tokens. After a user logs in we no longer have access to their password hence I can not use the password grant to get them an access token to our oauth based system. What are the recommended approaches to generate this access token. What I have looked into so far:
impersonation (token exchange)
custom keycloak userstore SPI that validates user with blank password
I guess using a client credential flow to generate a token that tries to match the users roles and attributes.
It seems to be a use case that is not well supported by oauth2?
It seems to be a use case that is not well supported by oauth2?
Your use-case seems to match those defined in the OAuth 2.0 Token Exchange specification
One common use case for an STS (as alluded to in the previous section)
is to allow a resource server A to make calls to a backend service C
on behalf of the requesting user B.
For this approach, you will need to configure in the appropriate Keycloak realm your legacy system as Identity Provider. So that you create a trust-relationship between the legacy system and Keycloak. Afterwards, you can exchange the token coming from the legacy system (resulting from the user authentication) for a token of the aforementioned realm. Depending upon your setup you might need protocol mappers that map the legacy system roles to the roles in the Keycloak realm. All of this is assuming that your legacy system is to a certain extend Oauth2 compliant.
Otherwise, another approach is for your legacy system, to call a confidential client on Keycloak and pass along some claims (e.g., the user roles). This is assuming that your legacy system can securely store the client secret. All of this, of course, depends upon the concrete characteristics of your setup.

How to authenticate mobile app to web service using Azure AD?

Currently I have this setup:
At login, and in every subsequent request after login, a mobile application that I have built uses Basic Authentication to authenticate the user with a web service that serves the app with information it requests.
On every request the Authorization header is inspected, the password and username are extracted from the header, the password is hashed using a proprietary DLL (so the web service doesn't actually contain the hashing algorithm) and compared to the hashed password associated with the username that is stored in the database.
I have now been asked to include Azure AD SSO in the login options.
After reading much about the topic, this looks seems to me like the setup:
I'm curious about a few things:
Is this setup correct, more or less?
Does the app send the Identity Token to the web service? If so, how does the webservice validate that token?
Is it correct that the webservice can match the Azure Identity to the DB user using one of the claims in the Security Token?
Where do Access Token fit in this picture?
Thanks for the help!
(Side Note: I know that Basic Authentication is not the preferred way to go in the first scenario. This was a temporary decision till we developed the token handling code, it only works using HTTPS and this is an internal application - you wouldn't be able to activate the app unless you have a code we give you)
I have little experience in azure ad but I think we could talk about your case.
First, whatever id token and access token are both jwt token, so to your web service application, you need to use jwt decode library to decrypt the token and get claims it contains. Here we need to know the difference between id token and access token, and I think you'll know that for your web service application, if it's more likely to play the role of an api application, you need to use access token because this token also contains user information. Then you need to add code in your program to decode the token and check if it's a 'valid' token for the request.(Because you've used azure ad to achieve the login part, you don't need to use your custom login part.)
Next, the signing in feature provided by azure ad requires to use account and password in the tenant which azure ad belongs to, the user accounts may look like xx#xx.onmicrosoft.com, it doesn't required to keep sycn with the accounts in your database, so it's difficult and needless for you to compare the user name obtained from the decoded token with those in your database. Because when your web service received the token(id or access token), that means someone has passed the authentication from azure ad. The token contains user information including role, expired time etc. You need to check if the token has expired and if has the correct scope. (Let's see a common situation, microsoft provides many graph apis to call, when accessing these api, we need to provide access token in request head with matching scope, e.g. https://graph.microsoft.com/v1.0/me
requires a delegated api permission of User.Read)
To sum up here, if your web service just required the users in your database to sign in then can be access, id token and access token are both suitable for you because they both contains user name like 'xx#xx.onmicrosoft.com', what you need to do is decode the token and check if the token has expired and whether this user exists in your database(you may set up a mapping between them).

How to authorize logged in users using Google Auth JWT? (Picture)

I currently have a backend running on AWS Lambda and I'm using DynamoDB as a database. In Dynamo, there is a list of users and each user has specific permissions as to what routes they have access to through the API. There is no issue here.
I have not built the front end yet, but I will be logging in users using Google Auth, more specifically with the react-google-login component.
My question is: Once a user is logged in to the site, should I trust the JWT from Google (after verifying its legitimacy
here with the Google API) which returns the user information (Name, Email), lookup the user item inside of Dynamo to retrieve their permissions, and then serve their request?
This seems like the logical thing to do but I was looking for some confirmation. My one worry is that someone could use a supervisors name & email to authorize a request but if the lambda must accept a JWT created by Google as entry, I believe this problem is solved correct?
I have API Keys as well for every user for some external functionality, but I have that covered since it's just a Dynamo call away. My only concern is with the front end requests to Lambda since I do not want to roll my own auth/jwt.
Here is what I was envisioning.
Thank you!
Normally you should use access tokens for that purpose. The ID token should be meant only to authenticate the user, and the access token should be used to authorize access.
The best scenario would be to have a separate Authorization Server which could issue access tokens, and there are some open source solutions out there which you can use.
If you really don't want to setup your own AS then you could follow the scenario you outlined - the part with verifying JWT from Google and checking permissions in the DynamoDB is what the Authorization Server would normally do to issue an access token.
Just remember to thoroughly validate the incoming JWT - not only the signature with Google, but also check if that is a token created for your client / audience, etc. Otherwise someone could take a Google ID token JWT from their client and gain access to your API. This article lists best security practices when working with JWTs.
Also remember that ID tokens might have short expiration times and there are no means of automatically refreshing them (like you can do it with a refresh token in case of an access token), so you might end up having to reauthenticate quite often.

How to implement OpenID Connect authentication with 3rd party IDPs in a microservices architecture

For the past 10+ days I've read an watched ALL the content I could find on understanding OAuth2 and OpenID Connect, only to find that many people disagree on the implementation, which really confuses me.
To my understanding, all the articles and examples I found assume you want access to eg. google calendar, profile info or emails if you eg. login with google, but I do NOT need to access other than my own API's - I only want to use Google, Facebook etc for logging in, and getting an id which I can link to my user in my own database - nothing more than that.
I'll try illustrate my use case and use that as an example.
A note on the diagram: the Authentication service could probably be built into the API Gateway - not that i matters for this example, since this is not about "where to do it", but "how to do it the best way" possible, for an architecture such as mine, where it's used for my own API's / Microservices, and not accessing Google, Facebook etc. external API's
If you can understand what I'm trying to illustrate with this diagram above, please tell me if I've misunderstood this.
The most basic requirements for this architecture you see here are:
Users can login with Google, Facebook, etc.
The same login will be used for all micro-services
OpenId user will have a linked account in the database
User access is defined in my own db, based on groups, roles and permissions
I do not intend to use external API's after the user is authenticated and logged in. No need for ever accessing a users calendar, email etc. so I really just need the authentication part and nothing else (proof of successful login). All user access is defined in my own database.
So a few fundamental questions comes to mind.
First of all, is OpenID Connect even the right tool for the job for authentication only (I'll have no use for authorization, since I will not need read/write access to google / facebook API's other than getting the ID from authenticating)?
People generally do not agree on whether to use the ID or Access token for accessing your own API's. As far as I understand the ID token is for the client (user-agent) only, and the access token is for eg. accessing google calendar, emails etc.... External API's of the OpenID Provider... but since I'll only be accessing my own API's, do I event need the access token or the ID token - what is the correct way to protect your own API's?
If the ID token is really just for the client, so it can show eg. currently logged in user, without going to the DB, I have 0 use for it, since I'll probably query the user from from the db and store it in redux for my react frontend app.
Dilemma: To store user details, groups, roles and permission inside JWT or not for API authorization?
By only storing the user identifier in the token, it means that I always allow authenticated users that has a valid token, to call endpoints BEFORE authorization and first then determine access based on the db query result and the permissions in my own database.
By storing more data about the user inside the JWT, it means that in some cases, I'd be able to do the authorization / access (group, role, permission) check before hitting the API - only possible with user info, groups, roles and permission stored inside a JWT issued upon login. In some cases it would not be possible due to eg. the CMS content access permissions being on a per-node level. But still it would mean a little better performance.
As you can see on the diagram I'm sending all API requests through the gateway, which will (in itself or with an authentication service) translate the opaque access token into some JWT with an identifier, so I can identify the user in the graph database - and then verify if the user has the required groups, roles and permissions - not from an external API, but from my own database like you see on the diagram.
This seems like a lot of work on every request, even if the services can share the JWT in case multiple services should need to cross call each other.
The advantage of always looking up the user, and his permissions in the db, is naturally that the moment the user access levels change, he is denied/granted access immediately and it will always be in sync. If I store the user details, groups, roles and permission inside a JWT and persist that in the client localstorage, I guess it could pose a security issue right, and it would be pretty hard to update the user info, groups, roles and permissions inside that JWT?
One big advantage of storing user access levels and info inside the JWT is of course that in many cases I'd be able to block the user from calling certain API's, instead of having to determine access after a db lookup.
So the whole token translation thing means increased security at the cost of performance, but is is generally recommended and worth it? Or is it safe enough to store user info and groups, roles, permissions inside the JWT?
If yes, do I store all that information from my own DB in the ID Token, Access token or a 3rd token - what token is sent to the API and determines if the user should be granted access to a given resource based on his permissions in the db? Do I really need an access token if I don't need to interact with the ID providers API? Or do I store and append all my groups, roles, permissions inside the ID token (that doesn't seem clean to me) issued by OpenID connect, and call the API and authorize my own API endpoints using that, even if some say you should never use the ID token to access an API? Or do I create a new JWT to store all the info fetched from my database, which is to be used for deciding if the user can access a given resource / API endpoint?
Please do not just link to general specs or general info, since I've already read it all - I just failed to understand how to apply all that info to my actual use case (the diagram above). Try to please be as concrete as possible.
Made another attempt to try and simply the flow:
The following answer does only apply for a OpenID Connect authentication flow with a 3rd party IDP (like Google). It does not apply for an architecture where you host your own IDP.
(There are some API gateways (e.g Tyk or Kong) which support OpenID Connect out of the box.)
You can use JWTs (ID token) to secure your APIs. However, this has one disadvantage. JWTs cannot be revoked easily.
I would not recommend this. Instead you should implement an OAuth2 authorization server which issues access tokens for your API. (In this case, you have two OAuth2 flows. One for authentication and one for authorization. The ID and access token from the IDP are used only for authentication.)
The following picture shows a setup where the API gateway and authentication/authorization server are two separate services. (As mentioned above, the authentication/authorization can also be done by the API gateway.)
The authentication flow (Authorization Code Grant) calls are marked blue. The authorization flow (Implicit Grant) calls are marked green.
1: Your web app is loaded from the app server.
2a: The user clicks on your login button, your web app builds the authorization URL and opens it. (See: Authorization Request)
2b: Because the user hasn't authenticated and has no valid session with your authorization server, the URL he wanted to access is stored and your authorization server responds with a redirect to its login page.
3: The login page is loaded from your authorization server.
4a: The user clicks on "Login with ...".
4b: Your authorization server builds the IDP authorization URL and responds with a redirect to it. (See: Authentication Request)
5a: The IDP authorization URL is opend.
5b: Because the user hasn't authenticated and has no valid session with the IDP, the URL he wanted to access is stored and the IDP responds with a redirect to its login page.
6: The login page is loaded from the IDP.
7a: The user fills in his credentials and clicks on the login button.
7b: The IDP checks the credentials, creates a new session and responds with a redirect to the stored URL.
8a: The IDP authorization URL is opend again.
(The approval steps are ignored here for simplicity.)
8b: The IDP creates an authorization and responds with a redirect to the callback URL of your authorization server. (See: Authentication Response)
9a: The callback URL is opened.
9b: Your authorization server extracts the authorization code from the callback URL.
10a: Your authorization server calls the IDP's token endpoint, gets an ID and access token and validates the data in the ID token. (See: Token Request)
(10b: Your authorization server calls the IDP's user info endpoint if some needed claims aren't available in the ID token.)
11a/b: Your authorization server queries/creates the user in your service/DB, creates a new session and responds with a redirect to the stored URL.
12a: The authorization URL is opend again.
(The approval steps are ignored here for simplicity.)
12b/+13a/b: Your authorization server creates/gets the authorization (creates access token) and responds with a redirect to the callback URL of your web app. (See: Access Token Response)
14a: The callback URL is opened.
14b: Your web app extracts the access token from the callback URL.
15: Your web app makes an API call.
16/17/18: The API gateway checks the access token, exchanges the access token with an JWT (which contains user infos, ...) and forwards the call.
A setup where the authorization server calls the API gateway is also possible. In this case, after the authorization is done, the authorization server passes the access token and JWT to the API gateway. Here, however, everytime the user infos change the authorization server has to "inform" the API gateway.
This is a very long question. But I believe most can be summarised by answering below,
To my understanding, all the articles and examples I found assume you want access to eg. google calendar, profile info or emails if you eg. login with google,
You do not necessarily use Access token (ID token in some occasions) to access the services offered by token issuer.You can consume tokens by your own APIs. What these Identity Providers (synonym to Authorization server, or IDP in shorthand) is to hold identities of end users. For example, typical internet have a Facebook account. With OAuth and OpenID Connect, the same user get the ability to consume your API or any OAuth/OIDC accepted service. This reduce user profile creation for end users.
In corporate domain, OAuth and OIDC serves the same purpose. Having a single Azure AD account lets you to consume MS Word as well as Azure AD's OIDC will issue tokens which can be used to Authorise against an in-house API or an third party ERP product (used in organization) which support OIDC based authentication. Hope it's clear now
A note on the diagram is that the Authentication service could probably be built into the API Gateway - not sure if that would be better?
If you are planning to implement an API gateway, think twice. If things are small scale and if you think you can maintain it, then go ahead. But consider about API managers which could provide most of your required functionalities. I welcome you to read this article about WSO2 API manger and understand its capabilities (No I'm not working for them).
For example, that API manager has built in authentication handling mechanism for OAuth and OIDC. It can handle API authentication with simple set of configurations. With such solution you get rid of the requirement of implement everything.
What if you can't use an API manager and has to do it yourself
OpenID Connect is for authentication. Your application can validate the id token and authenticate end user. To access APIs through API Gateway, I think you should utilise Access token.
To validate the access token, you can use introspection endpoint of the identity provider. And to get user information, you can use user-info endpoint.
Once access token is validated, API gateway could create a session for a limited time (ideally to be less or equal to access token lifetime). Consequent requests should come with this session to accept by API gateway. Alternatively, you can still use validated access token. Since you validated it at the first call, you may cache for a certain time period thus avoiding round trips to validations.
To validate user details, permission and other grants, well you must wither bind user to a session or else associate user to access token from API gateway at token validation. I'm also not super clear about this as I have no idea on how your DB logic works.
First Appreciate your patience in writing a very valuable question in this forum
we too have same situation and problem
I want to go through ,as images are blocked in our company in detail
Was trying to draw paralles to similar one quoted in the book
Advance API In Practise - Prabath Siriwerdena [ page 269]Federating access to API's Chapter. Definitely worth reading of his works
API GW should invoke Token Exchange OAUTH2.0 Profile to IDP [ provided the IDP should support TOken Exchange profile for OAUTH 2.0
The Absence of API Gateway , will result in quite bespoke development
for Access Control for each API Check
you land up in having this check at each of the api or microservice [ either as library which does work for you as a reusable code]
definitely will become a choking point.]

How to handle user registration in OAuth Server when it is separated from the Resource Server?

I am working on an application in which users with elevated roles (administrators) can create other users (with lower roles). I'm using PHP (Slim framework) and MySQL.
So far i have a Resource Server which can be accessed through a REST API with access tokens obtained from the OAuth Server using the Password Grant. The two servers have separate databases. There is also a Web Server which provides a dashboard where administrators log in and create new users by setting their username, password and other generic information.
Considering the fact that both the Resource Server and the OAuth Server have to store user data in their respective db tables, would it be ok if the Resource Server, upon a new user request, stores the generic user info in it's "users" table AND sends a request with the user credentials to the OAuth Server which will add a new entry in it's "oauth_users" table ? If not, what would be the best and secure way to achieve this functionality ?
Thank you in advance!
This approach works for us.
On the Auth Server db side you have to store only: user id, redirect url's and authorized service level (scopes) configured; the access tokens granted; and other authorization required data (roles in your case).
The Login Server db, stores: user id, password and other authentication related data.
The User resource service (commonly a RESTFul API) should store: user id and other personal data.
Upon a new user request of a secured resource data (some scope is needed here), redirects to the Login Server, with this successful authentication, redirects to the Auth Server to grant permissions using that scope, generate an access token and redirect to the secured resource with an access token, the resource server validates the token and the scope (some implementations also make another call to the Auth Server to validate this using JWT) to finally allow the initial user request.
In general, I personally use the DRY principle with this kind of architecture.
Cheers!

Resources