superset: Cannot autheticate on API. Get the tokens (JWT and csrf) but all responses are "401"

I cannot use the API succefully for any request (except to get the secutiry tokens), always getting " Response 401" for any request.

How to reproduce the bug

On the docker container where the superset is running:

>>>
import requests

session = requests.session()

jwt_token = session.post(
    url='http://localhost:8088/api/v1/security/login',
    json={
    "username": "admin",
    "password": "admin",
    "refresh": False,
    "provider": "db"
    }
).json()["access_token"]

csrf_token = session.get(
    url='http://localhost:8088/api/v1/security/csrf_token/',
    headers={
        'Authorization': f'Bearer {jwt_token}',
    }
).json()["result"]

headers = {
    'accept': 'application/json',
    'Authorization': f'Bearer {jwt_token}',
    'X-CSRFToken': csrf_token,
}

#trying to use the "current user" request as a test
response = requests.get('http://localhost:8088/api/v1/me', headers=headers)

session.close()`

response

Expected results

{ “result”: { “email”: “admin@superset.com”, “first_name”: “Superset”, “id”: 1, “is_active”: true, “is_anonymous”: false, “last_name”: “Admin”, “username”: “admin” } }

Actual results

>>> response
<Response [401]>

Screenshots

Environment

(please complete the following information):

  • superset version: v1.0.0
  • python version: Python 3.8.12

Checklist

  • [ x] I have checked the superset logs for python stacktraces and included it here as text if there are any.
  • [x ] I have reproduced the issue with at least the latest released version of superset.
  • [ x] I have checked the issue tracker for the same issue and I haven’t found one similar.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 18 (2 by maintainers)

Most upvoted comments

I can confirm that this issue still exists with the latest release. Expected behavior, what goes wrong and steps to reproduce are the same as my first report.

versions:

apache-superset==2.1.0
Python 3.8.16

@rusackas Could you please re open this issue?

Actually I was able to solve this problem.

import requests
# from bs4 import BeautifulSoup

username = "admin"
password = "admin"
session = requests.session()

login_form = session.post('http://localhost:8088/login')
# soup = BeautifulSoup(login_form.text, 'html.parser')
# csrf_token = soup.find('input',{'id':'csrf_token'})['value']
data = {
  'username': username,
  'password': password,
  # 'csrf_token': csrf_token
}
response = session.post('http://localhost:8088/login', data=data)
response = session.get('http://localhost:8088/api/v1/me')

This is a work around to make this api work. Comment out the lines in above code, if you want CSRF token i.e iff you enabled the flag in config

This issue seems to be present in version 3.0.0 as well. Running with Docker Compose. Requests to /api/v1/me/roles is always returning 401. This seems to break the embed dashboard feature. It would be great if anyone on the Superset side could look into this.

Instead of

#trying to use the "current user" request as a test
response = requests.get('http://localhost:8088/api/v1/me', headers=headers)

you should try:

session.headers.update(headers)

response = session.get('http://localhost:8088/api/v1/me') 

@michael-s-molina Hi, I am using the lastest version of Superset, but still facing this issue, can we re-open it? All settings are leave as default except FAB_ADD_SECURITY_API = True I am able to login, get csrf_token and call every other api except /api/v1/me/, it return 401

Hi Guys,

We are facing similar issue while authenticating superset API request (Superset version - 2.0.1). I have tried all the solution listed here but unfortunately nothing worked for me. Do we have any update on the issue?

Thanks!

After a couple of hours doing debugging it seems that I could resolve the problem with a temporary solution. In my case, I was requesting POST:api/v1/chart/data using the JWT authentication method. For this endpoint we have permission_str=can_read and the class_permission_name=Chart. somewhere in flask_appbuilder/security/decorators.py:84 we have:

            if current_app.appbuilder.sm.is_item_public(
                permission_str, class_permission_name
            ):

In my running superset instance, reading a chart was a public action but only some of the charts were actually public. So the decorator prevents execution of verify_jwt_in_request() before processing the request, because of can read on Chart is in permissions of the Public role.

Temporary Solution

On the superset UI I edited the role of public and removed can read on Chart from its permissions.

Instead of

#trying to use the "current user" request as a test
response = requests.get('http://localhost:8088/api/v1/me', headers=headers)

you should try:

session.headers.update(headers)

response = session.get('http://localhost:8088/api/v1/me') 

This didn’t work now. The code is accessing g.user from flask_login. The flask_login doesn’t load the user when the request is sent from the api. I think there should be a better solution for the new version of code.