adimyth opened a new issue, #22258:
URL: https://github.com/apache/superset/issues/22258

   I am trying to embed a superset dashboard into a simple front-end 
application. However, when the embedded dashboard always throws `403: 
Forbidden`. I am pretty sure I have set the correct permissions and everything. 
I even tried accessing it using `admin` user, still it fails.
   
   ## How to reproduce the bug
   
   The source for the application can be found here - 
https://github.com/adimyth/superset_embedded
   
   ### `superset` application
   Added the following configuration in `superset_config.py`
   
   ```python
   FEATURE_FLAGS = {"ALERT_REPORTS": True, "EMBEDDED_SUPERSET": True}
   
   SESSION_COOKIE_SAMESITE = None
   ENABLE_PROXY_FIX = True
   PUBLIC_ROLE_LIKE_GAMMA = True
   CORS_OPTIONS = {
       'supports_credentials': True,
       'allow_headers': ['*'],
       'resources': ['*'],
       'origins': ['http://localhost:8088', 'http://localhost:8000']
   }
   ```
   This gave me the following dashboard it to embed into my application
   ![Screenshot 2022-11-29 at 2 28 54 
PM](https://user-images.githubusercontent.com/26377913/204484479-755a7e0b-8cf8-45b2-8b41-1038ea9dd631.png)
   
   ### `frontend` application
   
   ```html
   <head>
       <script src="https://unpkg.com/@preset-sdk/embedded";></script>
       <style>
           iframe {
               height: 100%;
               width: 100%;
               border: none;
           }
       </style>
   </head>
   <body>
       <p id="dashboard-container"> </p>
       <script>
           // 1. Request guest_token from our backend, which runs at 
localhost:8000 by default 
               async function fetchGuestTokenFromBackend() {
                   let response = await 
fetch('http://127.0.0.1:8000/guest-token');
                   let data = await response.json()
                   return data
           }
   
           // 2. Uses Preset Embedded SDK to embed the dashboard as iFrame
           const myDashboard = presetSdk.embedDashboard({
             id: "{{ DASHBOARD_ID }}",
             supersetDomain: "{{ SUPERSET_DOMAIN }}",
             mountPoint: document.getElementById("dashboard-container"),
             fetchGuestToken: () => fetchGuestTokenFromBackend(),
             dashboardUiConfig: { hideTitle: true, hideChartControls: true}
           });
       </script>
   </body>
   ```
   The frontend simply calls the `/guest-token` from backend and passes it to 
the `presetSdk.embedDashboard`
   
   ### `backend` application
   The `/guest-token` endpoint simply calls 2 methods from the helper 
(superset.py) file
   ```python
   @app.get("/guest-token")
   async def analytics_view(request: Request):
       access_token = superset.authenticate()
       guest_token = superset.get_guest_token_for_dashboard(
           dashboard_id=DASHBOARD_ID, access_token=access_token
       )
       return guest_token
   ```
   
   The helper has 2 methods - `authenticate()` which authenticates the 
superset-admin user & `get_guest_token_for_dashboard` which is used to generate 
access token for the guest user
   ```python
   import json
   import os
   
   import requests
   from dotenv import load_dotenv
   
   load_dotenv()
   
   
   URL_AUTH = os.getenv("URL_AUTH")
   URL_GUEST_TOKEN = os.getenv("URL_GUEST_TOKEN")
   USERNAME = os.getenv("USERNAME")
   FIRST_NAMER = os.getenv("FIRST_NAMER")
   LAST_NAME = os.getenv("LAST_NAME")
   
   
   def authenticate(
       username="admin",
       password="admin",
   ):
       response = requests.post(
           "http://localhost:8088/api/v1/security/login";,
           headers={
               "Content-Type": "application/json",
               "Accept": "application/json",
               "Access-Control-Allow-Origin": "http://localhost:8000";,
           },
           data=json.dumps(
               {
                   "username": username,
                   "password": password,
                   "provider": "db"
               }
           ),
       )
       return response.json()["access_token"]
   
   
   def get_guest_token_for_dashboard(
       dashboard_id,
       access_token,
       username=USERNAME,
       first_name=FIRST_NAMER,
       last_name=LAST_NAME,
   ):
       response = requests.post(
           URL_GUEST_TOKEN,
           data=json.dumps(
               {
                   "user": {
                       "username": username,
                       "first_name": first_name,
                       "last_name": last_name,
                   },
                   "resources": [
                       {
                           "type": "dashboard",
                           "id": dashboard_id,
                       }
                   ],
                   "rls": [],
               }
           ),
           headers={
               "Authorization": "Bearer " + access_token,
               "Accept": "application/json",
               "Content-Type": "application/json",
           },
       )
       return response.json()["token"]
   ```
   
   Finally we pass environment variables. Note that the `DASHBOARD_ID` matches 
from the screenshot above. Also note that I am passing superset-admin creds to 
the embedded dashboard
   ```
   URL_AUTH=http://localhost:8088/api/v1/security/login
   URL_GUEST_TOKEN=http://localhost:8088/api/v1/security/guest_token/
   USERNAME=admin
   FIRST_NAMER=Supserset
   LAST_NAME=Admin
   DASHBOARD_ID=b0a944b2-4ab5-47b7-a31d-c3eca4c36397
   SUPERSET_DOMAIN=http://localhost:8088/
   ```
   
   ## Error
   When loading the frontend application which has the embedded dashboard, it 
returns -
   ```
   {"errors": [{"message": "403 Forbidden: You don't have the permission to 
access the requested resource. It is either read-protected or not readable by 
the server.", "error_type": "GENERIC_BACKEND_ERROR", "level": "error", "extra": 
{"issue_codes": [{"code": 1011, "message": "Issue 1011 - Superset encountered 
an unexpected error."}]}}]}
   ```
   
   ## Expected results
   I was expecting to see the actual dashboard in the frontend application
   
   
   ## Actual results
   ![Screenshot 2022-11-29 at 2 37 17 
PM](https://user-images.githubusercontent.com/26377913/204486368-d21af1ac-7b20-4d5e-9981-958f41d43ea5.png)
   
   What's surprising is that after decoding the guest token, we can clearly see 
that the user is superset admin & has access to the dashboard 🤯 
   ![Screenshot 2022-11-29 at 2 39 15 
PM](https://user-images.githubusercontent.com/26377913/204486870-af11d0a1-d0af-4d6e-979f-a3a7d98ada2c.png)
   
   ### Environment
   
   (please complete the following information):
   
   - browser type and version: Chrome
   - superset version: Built from the latest code as of 29th Nov
   - python version: 3.9
   - node.js version: NA
   - any feature flags active: `{"ALERT_REPORTS": True, "EMBEDDED_SUPERSET": 
True}`
   
   ### Checklist
   
   Make sure to follow these steps before submitting your issue - thank you!
   
   - [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.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to