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

OAuth 2 support #2401

Closed
simonpoole opened this issue Sep 18, 2023 · 3 comments · Fixed by #2469
Closed

OAuth 2 support #2401

simonpoole opened this issue Sep 18, 2023 · 3 comments · Fixed by #2469

Comments

@simonpoole
Copy link
Collaborator

No description provided.

@simonpoole simonpoole added this to the 20.0 milestone Sep 18, 2023
@tomhughes
Copy link

See also openstreetmap/operations#867

@simonpoole
Copy link
Collaborator Author

Candidate OAuth 2 implementations

https://github.com/openid/AppAuth-Android

https://bitbucket.org/connect2id/oauth-2.0-sdk-with-openid-connect-extensions/src/master/

https://github.com/dmfs/oauth2-essentials

https://github.com/scribejava/scribejava

The later two seem the most likely candidates as they seem to provide at least some http client independence.

@westnordost
Copy link

westnordost commented Dec 16, 2023

For StreetComplete, I implemented it myself. Half of it is the fragment that shows the web view etc. anyway, and it is really not that much (perhaps 300 source lines of code).

The full OAuth 2 spec is quite large and offers quite some different authorization flows plus a ton of optional extra-features but OSM just uses the (recommended) authorization-code grant type and almost no extra-features.

Here is some info in case you decide to implement it yourself, too:

Authorize requests

Add the request header Authorization: Bearer <the OAuth2 access token> to any authorized request to the OSM API to authorize the request in your code.

Get the access token

Basic steps in a nutshell

  1. open the authorization endpoint with appropriate URL parameters in the browser or web view
  2. let the user accept or deny the permission request in the browser or web view. The authorization endpoint will call the previously specified redirect URI (aka callback URI) with parameters in either case.
  3. extract the authorization code from the URL parameters of the callback and presenting the authorization code to the access token endpoint, retrieve the access token

Details (OAuth 2 Specification)

  • OpenStreetMap only uses the Authorization Code Grant type authorization flow as described in Section 4.1 of the spec, so the rest is not relevant for us.

  • RFC 7636 describes an optional addon to the OAuth 2.0 spec which OpenStreetMap supports and makes the authorization more secure: A code PKCE challenge. Both JOSM and StreetComplete implemented this in order to be forward-compatible to OAuth 2.1 spec as it is described as mandatory, there.

  • OpenStreetMap further is RFC8414 compliant, which means that there is this JSON file https://www.openstreetmap.org/.well-known/oauth-authorization-server on OSM which lists its OAuth 2.0 features, capabilities and endpoint URLs. (So, now you see, that the implementation for an OAuth client that should be able to support all possible capabilities would be quite some work.)
    JOSM reads this JSON in order to get the authorization and access token endpoint to be forward-compatible in case one day the endpoints change. StreetComplete just has these two urls hardcoded (I didn't see the point).

  • OpenStreetMap (currently) issues tokens that never expire, so, it does also not issue refresh tokens. For forward compatibility, there is some implementation for that in JOSM, IIRC.

  • According to the specification, it is allowed that the server does not grant all requested scopes (=permissions) based on the user's choice, just like this was the case for OAuth 1.0a. The UI on osm.org does currently not allow it, but that may change. StreetComplete handles this case.

Implementations

(For me it is easier to read code than to read specification to understand...)

StreetComplete

  • OAuthAuthorization.kt - represents one OAuth 2 authorization flow (~120 source lines of code)

  • OAuthFragment.kt - the fragment with WebView that is the UI part of the authorization flow (~150 source lines of code)

  • UserModule.kt - just contains some constants, e.g. which permissions to requests, the API endpoints,...

(Pull request that replaced OAuth 1.0a with OAuth 2.0: streetcomplete/StreetComplete#5383)

JOSM

simonpoole added a commit that referenced this issue Jan 6, 2024
This adds a minimal implementation of OAuth 2 as that works (likely
only) with the current OpenStreetMap API.

Fixes #2401
simonpoole added a commit that referenced this issue Jan 6, 2024
This adds a minimal implementation of OAuth 2 as that works (likely
only) with the current OpenStreetMap API.

Fixes #2401
simonpoole added a commit that referenced this issue Jan 6, 2024
This adds a minimal implementation of OAuth 2 that works (likely
only) with the current OpenStreetMap API.

Fixes #2401
simonpoole added a commit that referenced this issue Jan 6, 2024
This adds a minimal implementation of OAuth 2 that works (likely
only) with the current OpenStreetMap API.

Fixes #2401
@simonpoole simonpoole moved this to Done in Vespucci Planning May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants