apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
61.98k stars 13.59k forks source link

Superset access_token api is throwing internal server error #30385

Open sundar68 opened 2 days ago

sundar68 commented 2 days ago

Bug description

Superset is working fine when try to use sdk, while fetching accesstoken it's throwing 500 error. API: /api/v1/security/login payload:

password: "****"
provider: "db"
refresh: true
username: "****"

Response: {"message":"Fatal error"}

Tried giving Gamma & public user credentials and Admin user credentials, but same error. When I tried to hit from swagger getting "Not Authorized error"

 async function fetchAccessToken() {
        try {
          const body = {
            username: "***",
            password: "***",
            provider: "db",
            refresh: true,
          }

          const response = await fetch(
            "http://localhost:8088/api/v1/security/login",
            {
              method: "POST",
              body: JSON.stringify(body),
              headers: {
                "Content-Type": "application/json",
              },
            }
          )

          const jsonResponse = await response.json()
          return jsonResponse?.access_token
        } catch (e) {
          console.error("error")
        }
      }

This is my superset_config.py file

#custom
import sys
sys.path.insert(0, '/app/superset/')
from custom_security import CustomSecurityManager

ROW_LIMIT = 50000
SECRET_KEY = '*****'
SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:***:5432/superset'
# Flask-WTF flag for CSRF
WTF_CSRF_ENABLED = False
# Add endpoints that need to be exempt from CSRF protection
WTF_CSRF_EXEMPT_LIST = []
# A CSRF token that expires in 1 year
WTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365
# Set this API key to enable Mapbox visualizations
MAPBOX_API_KEY = ''

SUPERSET_WEBSERVER_TIMEOUT = 3000

#SQLLAB
SQLLAB_ASYNC_TIME_SEC=3600*6
SQLLAB_TIMEOUT=3600
SQLALCHEMY_POOL_SIZE = 45
SQLALCHEMY_MAX_OVERFLOW = 30
SQLALCHEMY_POOL_TIMEOUT = 180

FEATURE_FLAGS = {'DRILL_BY': True,
                 'DASHBOARD_CROSS_FILTERS': True,
                 "EMBEDDABLE_CHARTS": True,
                 "EMBEDDED_SUPERSET": True,
                 "DASHBOARD_NATIVE_FILTERS": True,
                 "DRILL_TO_DETAIL": True,
                 "ENABLE_TEMPLATE_PROCESSING": True,
                 "HORIZONTAL_FILTER_BAR": True,
                 "DASHBOARD_RBAC": True,
                 "DASHBOARD_VIRTUALIZATION": True,
                 "ALERT_REPORTS_NOTIFICATION_DRY_RUN": True,
                 "ALERT_REPORTS": True,
                 "TAGGING_SYSTEM": True,
                 }

#API
FAB_API_SWAGGER_UI = True
FAB_ADD_SECURITY_API = True

APP_NAME = "Vymo Superset"
LANGUAGES = {
    'en': {'flag': 'us', 'name': 'English'},
    "ja": {"flag": "jp", "name": "Japanese"},
}
JINJA_CONTEXT_ADDONS = {
    'my_crazy_macro': lambda x: x * 2,
}

#Embed
PUBLIC_ROLE_LIKE_GAMMA = True
GUEST_ROLE_NAME = "Gamma"
TALISMAN_ENABLED = False

#CORS
SESSION_COOKIE_HTTPONLY = False
SESSION_COOKIE_SECURE = False
ENABLE_PROXY_FIX = True
OVERRIDE_HTTP_HEADERS = {'X-Frame-Options': 'ALLOWALL'}
ENABLE_CORS = True
CORS_OPTIONS = {
    'supports_credentials': True,
    'allow_headers': ['*'],
    'resources': ['*'],
    'origins': ['*']
}

CUSTOM_SECURITY_MANAGER = CustomSecurityManager

How to reproduce the bug

Try to hit above mentioned api with above config file.

Screenshots/recordings

Screenshot 2024-09-25 at 4 08 51 PM Screenshot 2024-09-25 at 4 08 31 PM

Superset version

master / latest-dev

Python version

3.9

Node version

16

Browser

Chrome

Additional context

No response

Checklist

dosubot[bot] commented 2 days ago

Hey @sundar68! I'm here to help you with any issues or questions you have. Let's tackle this bug together!

I found some similar discussions and a closed issue that might be relevant to your problem:

  1. "/api/v1/me/ gives '401 Unauthorized' error even when I pass the access token in headers" [1].
  2. "Failed to retrieve token from superset" [2].
  3. "Superset API return 401 Access Denied: Invalid Credential even when I am using access_token from admin account" [3].
  4. A closed issue: "500: Internal server error" [4].

The closed issue suggested a solution involving downgrading certain packages:

pip uninstall wtforms
pip install wtforms==2.3.3
pip uninstall flask
pip install flask==2.0.3
pip uninstall werkzeug
pip install werkzeug==2.0.3

Regarding the 500 internal server error for the /api/v1/security/login endpoint, it is likely due to an issue within the guest_token method. Here are some potential causes:

  1. Validation Errors: If the payload does not conform to the expected schema, a ValidationError will be raised. This should return a 400 error, but if there is an unhandled validation issue, it could result in a 500 error.
  2. Guest Token Validator Hook: If the GUEST_TOKEN_VALIDATOR_HOOK is not callable or fails validation, it raises a SupersetGenericErrorException or ValidationError, respectively. If these exceptions are not properly caught, they could result in a 500 error.
  3. Token Creation Issues: If there is an issue with the create_guest_access_token method, it could also result in a 500 error.

Here is the relevant code snippet that could be causing the issue:

try:
    body = guest_token_create_schema.load(request.json)
    self.appbuilder.sm.validate_guest_token_resources(body["resources"])
    guest_token_validator_hook = current_app.config.get("GUEST_TOKEN_VALIDATOR_HOOK")
    if guest_token_validator_hook is not None:
        if callable(guest_token_validator_hook):
            if not guest_token_validator_hook(body):
                raise ValidationError(message="Guest token validation failed")
        else:
            raise SupersetGenericErrorException(
                message="Guest token validator hook not callable"
            )
    token = self.appbuilder.sm.create_guest_access_token(
        body["user"], body["resources"], body["rls"]
    )
    return self.response(200, token=token)
except EmbeddedDashboardNotFoundError as error:
    return self.response_400(message=error.message)
except ValidationError as error:
    return self.response_400(message=error.messages)

To debug this issue, you should:

Additionally, the expected input and output schemas for the /api/v1/security/login endpoint are as follows:

Input Schema:

{
  "type": "object",
  "properties": {
    "password": {
      "description": "The password for authentication",
      "example": "complex-password",
      "type": "string"
    },
    "provider": {
      "description": "Choose an authentication provider",
      "enum": ["db", "ldap"],
      "example": "db",
      "type": "string"
    },
    "refresh": {
      "description": "If true a refresh token is provided also",
      "example": true,
      "type": "boolean"
    },
    "username": {
      "description": "The username for authentication",
      "example": "admin",
      "type": "string"
    }
  },
  "required": true
}

Output Schema:

{
  "type": "object",
  "properties": {
    "access_token": {
      "type": "string"
    },
    "refresh_token": {
      "type": "string"
    }
  }
}

[7]

To continue talking to Dosu, mention @dosu.