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

Introduce Authz contextvar and Authorization object #615

Merged
merged 49 commits into from
Oct 23, 2024

Conversation

byewokko
Copy link
Collaborator

@byewokko byewokko commented Oct 2, 2024

Summary

asab.web.auth.Authorization

  • Introduced asab.web.auth.Authorization object with request authorization and authentication details, such as CredentialsId, Username or Email.
  • It has RBAC checking methods has_resource_access, has_superuser_access and has_tenant_access, which return boolean value. Plus require_resource_access, require_superuser_access and require_tenant_access, which raise asab.exceptions.AccessDenied and log a warning when access is missing.
  • The Authorization object is stored in asab.contextvars.Authz context variable so it can be conveniently accessed from anywhere, including websocket methods.
  • Created Authorization objects are kept (or "cached") in AuthService and cleaned up when they expire.
  • ⚠️ DEPRECATION Handler arguments user_info and resources are now deprecated and their usage will log a warning at init time. Use the methods and attributes of Authorization instead, for example:

OLD

async def my_handler(request, *, user_info, resources):
	cred_id = user_info.get("sub")
	if "data:access" in resources or "authz:superuser" in resources:
		await do_stuff(cred_id)

NEW

async def my_handler(request):
	authz = asab.contextvars.Authz.get()
	cred_id = authz.CredentialsId
	if authz.has_resource_access("data:access"):
		await do_stuff(cred_id)

Automatic AuthService installation

  • ⚠️ DEPRECATION When the app has only one web container, you don't need to call AuthService.install(web_container), because it is called automatically at init time. Re-applying the installation will log a warning.

Other changes

  • Refactored asab.web.auth module for better reusability.
  • Updated ASAB docs on authorization.

Usage

import asab.contextvars

...

async def my_handler(request):
	authz = asab.contextvars.Authz.get()
	username = authz.Username

	print("{} tries to access my handler.".format(username))
	authz.require_resource_access("my-handler:access")  # This raises asab.exceptions.AccessDeniedError (HTTP 403) if access missing

	print("{} is authorized to access my handler.".format(username))

	if authz.is_superuser():
		print("{} is a superuser and can do anything!".format(username))
		await do_something_super_cool()
	else:
		await do_something_cool()

See https://github.com/TeskaLabs/asab/blob/feature/auth-contextvar/examples/web-auth.py for a full example.

@byewokko byewokko added the enhancement New feature or request label Oct 2, 2024
@byewokko byewokko self-assigned this Oct 2, 2024
@byewokko byewokko marked this pull request as draft October 3, 2024 16:24
@byewokko byewokko marked this pull request as ready for review October 3, 2024 16:26
@byewokko
Copy link
Collaborator Author

byewokko commented Oct 3, 2024

@ateska I want to introduce Authorization context which can be accessed and used similarly to the Tenant context. I'm still testing it but it's close to finished. What do you think?

@byewokko byewokko requested a review from ateska October 3, 2024 16:26
Copy link
Contributor

@ateska ateska left a comment

Choose a reason for hiding this comment

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

Discussed in person.

@byewokko byewokko requested a review from ateska October 10, 2024 15:51
@byewokko byewokko requested a review from Plesoun October 16, 2024 14:46
# Conflicts:
#	asab/contextvars.py
@Plesoun
Copy link
Contributor

Plesoun commented Oct 17, 2024

I like it, I looked over the implementation and I do not have anything to add. There are even updated examples etc...

asab/web/auth/service.py Outdated Show resolved Hide resolved
@byewokko byewokko merged commit 2a58ab6 into master Oct 23, 2024
8 checks passed
@byewokko byewokko deleted the feature/auth-contextvar branch October 23, 2024 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants