firebase-admin-python icon indicating copy to clipboard operation
firebase-admin-python copied to clipboard

Unable to create session cookie for tenant users

Open AndreaGiardini opened this issue 2 years ago • 17 comments

Hey everyone

I am setting up a python application and I would like to use firebase for authentication. For normal users the login flows works fine, my problem comes when I start using tenants.


When a user authenticates to my app, it gets a token and then, after verification, the token is exchanged for a long-lived session cookie. As mentioned before, this works great for normal users.

I am using the exact code described in the docs here: https://firebase.google.com/docs/auth/admin/manage-cookies#create_session_cookie

When I authenticate users that are part of a tenant though, I can't find a way to convert their token into a session cookie.

I tried using session_cookie = auth.create_session_cookie(id_token, expires_in=expires_in, app=tenant_app) but I get always the same error message:

Error while calling Auth service (UNSUPPORTED_TENANT_OPERATION).

Am I missing something ? I am using the latest version of firebase-admin

AndreaGiardini avatar Sep 19 '21 10:09 AndreaGiardini

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

google-oss-bot avatar Sep 19 '21 10:09 google-oss-bot

I found this thread of ~1 year ago... Is that still the case?

https://groups.google.com/g/firebase-talk/c/ShtMjbxLWBI


When I try to simulate the request here:

https://cloud.google.com/identity-platform/docs/reference/rest/v1/projects.tenants/createSessionCookie

I get:

{
  "error": {
    "code": 400,
    "message": "UNSUPPORTED_TENANT_OPERATION",
    "errors": [
      {
        "message": "UNSUPPORTED_TENANT_OPERATION",
        "domain": "global",
        "reason": "invalid"
      }
    ]
  }
}

AndreaGiardini avatar Sep 19 '21 12:09 AndreaGiardini

It is now supported in the backend, but was never exposed in the Python SDK. We can accept a PR to add this capability if anybody can spend some time on it.

It is available in our Node.js SDK if you want to see how it's implemented.

hiranya911 avatar Sep 20 '21 17:09 hiranya911

hey @hiranya911

Can you point me in the right direction? I've tried to call the API from firebase web interface but I got UNSUPPORTED_TENANT_OPERATION

AndreaGiardini avatar Sep 20 '21 18:09 AndreaGiardini

@hiranya911 Sorry to bother

I've tried different combinations from the web API Explorer but i always get the UNSUPPORTED_TENANT_OPERATION error. Since i can't get the API call to succeed i am not sure how can I implement the function in code.

Can you please point me in the right direction?

AndreaGiardini avatar Sep 22 '21 19:09 AndreaGiardini

Here's how it's implemented in Node.js: https://github.com/firebase/firebase-admin-node/blob/8610b943a91243ce0bd5ce984922ebba63fa3206/src/auth/auth.ts#L830-L845

It first verifies the ID token locally. Then makes a request to /projects/{projectId}/tenants/{tenantId}:createSessionCookie.

hiranya911 avatar Sep 22 '21 19:09 hiranya911

Hey @hiranya911

I ran an experiment using this patch over here: https://github.com/AndreaGiardini/firebase-admin-python/commit/0e620efe84821338379cf4e4768ebf2fd49dfd59

The method I am using is calling session_cookie = auth.create_session_cookie(id_token, expires_in=expires_in, tenant_id=dashboard.firebase_tenant_id) but I still get the same error. The request path and payload look good to me.

Traceback (most recent call last):
  File "/home/XXX/venv/lib/python3.8/site-packages/firebase_admin/_token_gen.py", line 239, in create_session_cookie
    body, http_resp = self.http_client.body_and_response('post', url, json=payload)
  File "/home/XXX/venv/lib/python3.8/site-packages/firebase_admin/_http_client.py", line 127, in body_and_response
    resp = self.request(method, url, **kwargs)
  File "/home/XXX/venv/lib/python3.8/site-packages/firebase_admin/_http_client.py", line 119, in request
    resp.raise_for_status()
  File "/home/XXX/venv/lib/python3.8/site-packages/requests/models.py", line 953, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://identitytoolkit.googleapis.com/v1/projects/$MYPROJECT/tenants/$MYTENANT:createSessionCookie

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/YYY/api/login.py", line 38, in session_login
    session_cookie = auth.create_session_cookie(id_token, expires_in=expires_in, tenant_id=dashboard.firebase_tenant_id)
  File "/home/XXX/venv/lib/python3.8/site-packages/firebase_admin/auth.py", line 243, in create_session_cookie
    return client._token_generator.create_session_cookie(id_token, expires_in, tenant_id=tenant_id)
  File "/home/XXX/venv/lib/python3.8/site-packages/firebase_admin/_token_gen.py", line 241, in create_session_cookie
    raise _auth_utils.handle_auth_backend_error(error)
firebase_admin.exceptions.InvalidArgumentError: Error while calling Auth service (UNSUPPORTED_TENANT_OPERATION).

As you can see from the stack trace, the right endpoint is called, but no matter how I do it, the result for me is always UNSUPPORTED_TENANT_OPERATION

Thank you for your help

AndreaGiardini avatar Sep 23 '21 13:09 AndreaGiardini

@bojeil-google do you have any ideas? I can't seem to find any integration tests that exercise this route, so I cannot confirm that it works.

hiranya911 avatar Sep 23 '21 19:09 hiranya911

Hey @hiranya911, I don't believe our backend supports tenant scoped session cookies. We will eventually support them but if I recall correctly, we decided at that time that we would implement the client side changes (relying on the backend error) so that when the backend API works, it wouldn't require additional client side changes. I believe our documentation does not document support for session cookies.

bojeil-google avatar Sep 23 '21 20:09 bojeil-google

@bojeil-google thank you for the clarification, that makes sense. Do you have an ETA for backend support for tenant-scoped session cookies? That would be pretty useful

AndreaGiardini avatar Sep 24 '21 06:09 AndreaGiardini

I ran into this same issue: The API indicates you need pass the tenant in: https://cloud.google.com/identity-platform/docs/reference/rest/v1/projects/createSessionCookie

The code here does not include tenant_id in the payload: https://github.com/firebase/firebase-admin-python/blob/ebf1bcd946fcc2cc97801f418bfebfbc45783f44/firebase_admin/_token_gen.py#L232

Even if you update the library to pass in the template, the backend server still fails with

Error while calling Auth service (UNSUPPORTED_TENANT_OPERATION).

Here is the change, we used to test with: https://github.com/huvrdata/firebase-admin-python/pull/1/files

sww314 avatar Oct 20 '21 16:10 sww314

I created an issue to track the problem in the API: https://issuetracker.google.com/issues/204377229

sww314 avatar Oct 28 '21 15:10 sww314

Hey, All

I am experiencing the same issue using firebase-admin java client

also tried testing it using both https://cloud.google.com/identity-platform/docs/reference/rest/v1/projects/createSessionCookie and https://cloud.google.com/identity-platform/docs/reference/rest/v1/projects.tenants/createSessionCookie

in all cases I am getting

{
  "error": {
    "code": 400,
    "message": "UNSUPPORTED_TENANT_OPERATION",
    "errors": [
      {
        "message": "UNSUPPORTED_TENANT_OPERATION",
        "domain": "global",
        "reason": "invalid"
      }
    ]
  }
}

fkowal avatar Feb 14 '22 10:02 fkowal

The issue in the public tracker was closed: https://issuetracker.google.com/issues/204377229

Does this mean the API is now available? And the client libraries need to fixed?

sww314 avatar Apr 12 '22 03:04 sww314

Hi everyone,

I'm also encountering this issue. I noticed that the discovery doc suggests that this functionality exists in the API. However, I have not been able to use the API Explorer to successfully call this method with an ID token that is generated from a tenant integration. Here's the error I get:

{
  "error": {
    "code": 400,
    "message": "INVALID_ID_TOKEN",
    "errors": [
      {
        "message": "INVALID_ID_TOKEN",
        "domain": "global",
        "reason": "invalid"
      }
    ]
  }
}

Is there a plan to provide this functionality? If not, what are some alternative approaches I can use?

I happen to be using the Go Admin SDK. Do you know when I can expect the SDK to be updated?

Thanks.

aryann avatar May 30 '22 05:05 aryann

Hi aryann,

Could you please provide more context concerning how to reproduce this (what were your steps)? For example, how was the idToken you passed in generated or where did it come from? I have tried reproducing this problem with the Node Admin SDK as well as curl commands and have been unsuccessful thus far.

eromney avatar Jun 01 '22 22:06 eromney

@hiranya911 This works now. We have been using in production for a month or two.

sww314 avatar Dec 22 '22 17:12 sww314