Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(superset-auth): Retrieve CSRF token with jwt auth for Superset #233

Merged
merged 3 commits into from
Aug 11, 2023

Conversation

Vitor-Avila
Copy link
Contributor

By default, Superset requires an X-CSRFToken header for some API requests. This was already handled when using the superset-cli command with basic auth (-u $username -p $password) but it wasn't handled when using jwt auth (--jwt-token $jwt).

This PR adds logic to include the CSRF token in the get_headers function.

Fixes #183.

@@ -161,4 +162,4 @@ def test_superset_jwt_auth(mocker: MockerFixture) -> None:
catch_exceptions=False,
)

JWTAuth.assert_called_with("SECRET")
JWTAuth.assert_called_with("SECRET", URL("http://localhost:8088/"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

baseurl is better suffix without /. Then you can prefix api/v1/security/csrf_token/ with /

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, @zephyring! The baseurl wasn't included in the constructor before, so I just copied what was sent to the runner.invoke here:

runner.invoke(
  superset_cli,
  ["--jwt-token=SECRET", "http://localhost:8088/", "export"],
  catch_exceptions=False,
)

The last trailing slash is included in other tests (like here and here), do you think this should be updated in other places as well?

I performed a local test using both http://localhost:8088/ and http://localhost:8088 in the CLI command and printed the endpoint -- both scenarios produced the same URL (http://localhost:8088/api/v1/security/csrf_token/) and the command worked properly.

Let me know your thoughts. Thank you!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a convention to have base_url ending without /. Not sure the other examples syntax for string / string is a good pattern to follow. maybe @betodealmeida ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should work either way here, we're using yarl for URL composition and it should do the right thing.

super().__init__()
self.token = token
self.baseurl = baseurl

def get_csrf_token(self, jwt: str) -> str:
Copy link
Member

@betodealmeida betodealmeida Aug 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to create a new Auth class, maybe SupersetJWTAuth, since the path api/v1/security/csrf_token/ is very specific to Superset. Otherwise this generic class becomes tightly coupled with Superset and it becomes hard to reuse it for other APIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohhhhh that makes sense! Just noticed this class is also used by dbt. Going to make these changes. Thank you!

@betodealmeida betodealmeida merged commit 5594625 into main Aug 11, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calling superset assets api with JWT token fails because no csrf token is used
3 participants