Repository navigation
OAuth2 Sessions - #785
OAuth2 Sessions #785antheng wants to merge 18 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #785 +/- ##
==========================================
+ Coverage 80.60% 80.80% +0.20%
==========================================
Files 90 93 +3
Lines 10366 10640 +274
==========================================
+ Hits 8355 8598 +243
- Misses 2011 2042 +31 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
On Fri, Sep 25, 2026 at 12:19:47AM -0700, Manon Marchand wrote:
@ManonMarchand commented on this pull request.
I'd rather have these dependencies as a new optional bundle
Agreed. Meanwhile, this is a scary amount of code, while I still
only have a very superficial understanding of OAuth2. So, I'd be
grateful if someone else could review this.
But then: Are there live (registered?) services that can be used with
that? I'd really like to try this, and perhaps we can even add a bit of
executable documentation (though I will give you working examples
would likely require working credentials... ouch).
|
|
I have no knowledge on OAuth2. If we don't find a reviewer I could try to persuade Gregory to help. +1: working examples would be nice so that we can try by ourselves |
Currently I'm using this fork with at this stage private OAuth2 protected resource however I have added some usage instructions to the docs in the latest commit. If someone were to test this fork on their own service supporting registration then I would be keen to hear how well it works to refine it further. |
|
Thank you for the PR. I will have a closer look and try it with services next week. Until then, a few points to consider:
|
|
There are a lot of merge commits of various flavours. Could you please rebase to smooth those out and make the branch history linear? Thanks! |
|
Here are a few observations to start with. Unlike X509 certificates and cookie, tokens are inherently very tricky to deal because they can be sent to the wrong destination and potentially replayed. It is even harder to used them with a public and generic client like
I also recommend adding support to RFC 9728 (protected_resources cross-check) if AS supports it. The implementation should allow users to opt out of some of these restrictions and also warn them when services have low security support. Failures should be as explicit as possible to allow users/service operators to take appropriate actions. |
… to mocks.py, with its instantiation done in conftest.py
… code fetch during device code auth. auth parameter to the pyvo auth2session request method. Add TODO stub to eventually come back to test support for implicit grant type
…tead of returning None on discovery/registration failures. Reuse client credentials from the request `auth` parameter to skip dynamic registration when they are known, and add test for this behaviour.
…or consistency and add types.
…th2 extras in doc building and testing. VOAuthSession and SessionStore can now be imported directly from pyvo.auth.oauth2
… the docs. Not possible to fix unless we use intersphinx
|
@andamian This aims to add the OAuth 2 parts of the AuthVO, so if you see any misalignment between the two, please flag it! @msdemlei @ManonMarchand The Data Central VO services will support this when the new version is released (as a test of the AuthVO). @antheng has created patches to vollt to also add support. I'll let people know when this is running on a public endpoint, so that people can play with it. This requires three parts (the authorization server, the resource server and the client (in this case pyvo)) all working, and setting up the authorization server and the resource server is not trivial. Some other comments on the PR:
|
|
It seems unlikely that the PR would be merged in requests-oauthlib, as the repo has not seen any activity since two years. Do you know if there could be a more active project that could support it? |
|
Given the commentary in #785 (comment), I would assume we cannot realistically pursue this to be included in the next release (in ~2 weeks time), but aiming for next May instead? Could/should we instead flip it to be a draft PR while there are active upstream blockers for it? |
|
OK, that sounds great! I tentatively add this to the next milestone then, no pressure if it won't get wrapped up, but it helps me to see what are blocking the releases. |
|
Given the number of changes that might need to be made and in turn reviewed again I am happy to make this a draft PR that can be later merged for the May release. This also gives us time to discuss further at IVOA
@ManonMarchand There are a few other oauth2 libraries we could use that seem to be in a more active state however they seem to lack the device code grant used currently. |
Introduces the new module
pyvo.auth.oauth2intended to act as a requests-like session for dispatching network calls towards oauth2 protected resources, usingrequests-oauthlibfor many operations.The new session class
pyvo.auth.oauth2.oauth2session.VOAuthSessionintends to emulate whats already been established inpyvo.auth.authsession.AuthSession, except for the functions that use the/capabilitiesendpoint as authentication methods are determined from the authorization metadata rather than those published to the endpoint.The session storage class
pyvo.auth.oauth2.sessionstore.SessionStorewhich the new session class uses, intends to also emulate the structure inpyvo.auth.authurls, however instead of storing the security methods for a given URL, we instead store another sessions like object which will contain the client credentials required to authenticate to a oauth2 protected resource, or a new one will be created via discovery through the Python interpreter.At the moment only
urn:ietf:params:oauth:grant-type:device_codegrant type is supported however the authentication process is structured to eventually add any grant types supported byoauthliband can be introduced in future PRs.On Protect Resource Request
On a given
_requestcall to a OAuth2 protected resource:WWW-Authenticatewith aresource_metadataproperty, follow the resource metadata to obtain the list of authorization servers. See RFC 9728/.well-known/openid-configurationor/.well-known/oauth-authorization-server, discover the valid grant types, and scopes. If thepyvo.auth.oauth2.VOAuthSessionobject is not configured with their own requests grant types and scopes we will simply use those advertised in the authorization server metadata, otherwise we will end up using an intersection between those configured with the object and those advertised. See RFC 8414client_idandclient_secretis passed to the request call, attempt dynamic registration as per RFC 7591 if aregistration_endpointis advertised in the authorization server metadata to obtain a dynamically allocated pair of client credentials. Construct a newrequests_oauthlib.OAuth2Sessionfor the requested URL with the new or explicit client id and secret.pyvo.auth.oauth2.VOAuthSessionobject.Helper functions
These functions were primarily to be used as individual steps within
authenticate_new_session_from_metadata, however can be used to individually as part of different processes if required:get_dynamic_client_credentials: If an authorization server supports it and with the registration endpoint exists, attempt to obtain a set of dynamic registration credentials. See RFC 7591find_as_metadata: Given a list of Authorization server base URLs, attempt to find their metadata. See RFC 8414token_from_device_code: Brings the user through the device_code grant for a given OAuth2Session, device authorization and token endpoint, using a set of client credentials. (see RFC 8628). This was intended to be merged intorequests-oauthlibat Add Support for Device Code Authorization requests/requests-oauthlib#574 however it has not yet been reviewed and thus this serves as a temporary function to use device code authorization until it or an equivalent function is merged intorequests-oauthlibAdded dependencies:
requests_oauthlib: Creating and storingrequests_oauthlib.OAuth2Sessions are the session objects being stored and created, and are the intended stored sessions. Attempts to use other Sesssion-like classes will need to support the same interfaces.keyring: For storing client secrets for the client id's in eachOAuth2Session.keyring.cryptfileis a dependency and provided as a default backend, however other backends can be configured