Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This page is starting as a collection of notes, design decisions, etc. related to implementing OAuth2 into Synapse. Part of the process has included considerations about developing our own library, or using an off-the-shelf solution like ORY Hydra. The information on this page may change as the project evolves.

...

VerbEndpointPurposeRequest Object/ParamsResponse Object/ParamsNotes
GET/oauth2/clients/{id}Get details about one client

Path param:

id: an existing OAuth2 Client ID

OAuth2Client

name: String

redirect_uri: String

client_id: Unique

created_by/on

modified_by/on

Supplemental params

The web layer can use this to get details about a client requesting authorization.
POST/oauth2/clientsCreate a client

OAuth2Client

name: String

redirect_uri: String

Supplemental params

OAuth2Client

name: String

redirect_uri: String

client_id: Unique

client_secret: String

created_by/on

modified_by/on

Supplemental params

Supplemental params could include the URL to a logo, link to a website for the app, terms of service, etc.

Typically the secret key is used to perform these actions, but if we give Synapse users a claim over an OAuth2 client, we could use their credentials.

DELETE/oauth2/clients/{id}Delete a client

Path param:

id: an existing OAuth2 Client ID

None
GET/oauth2/auth

Display the login/consent info to the user and prompt for an accept/reject

URL Parameters:

response_type: String (always "code")

client_id: Unique

redirect_uri: String (points to OAuth client)

scope: String

state: String

Web interface for Synapse authorization

The form should permit login and we must be able to include the request parameters in a new request

This endpoint should point to a web layer that can show a UI with a login form and display the access that the user can consent to, along with a prompt for the user to accept/reject.

We should think about using login cookies here to simplify the UX if a user is already logged into Synapse

POST/oauth2/authThe user grants access to the OAuth2 Client to access protected resources

URL Parameters:

response_type: String (always "code")

client_id: Unique

redirect_uri: String (points to OAuth client)

scope: String

state: String

Body:

LoginRequest (already exists)

If login is successful:

Redirect URL:

redirect_uri (provided in request)

Parameters:

code: the authorization code

state: the same value in the request

Should we include a LoginResponse body?

(Probably not, if the body is kept in the redirect then we may be exposing a session token to the 3rd party client)

Who should execute this? The User Agent or the Web Layer on behalf of the user agent?

Question: how to handle with various Synapse IdPs? (E.g. Synapse users who sign in with Google accounts).

The "state" parameter is designed to avoid CSRF attacks. More info.

POST/oauth2/tokenCalled by a client to get an access token

Body:

OAuth2AuthorizationCodeTokenRequest

grant_type: String (always "authorization_code" for this call)

code: String (the authorization code)

redirect_uri: String (should be the same as previous redirect uri)

client_id: Unique

client_secret: String

Body:

OAuth2AccessToken

access_token: String

token_type: String ("Bearer")

expires_in: Integer (seconds)

refresh_token: String

(optionally, scope)

The redirect URI should be validated here before granting a token, along with the credentials in the request. More info.

The token type in almost all OAuth2 cases is "Bearer". We can use a different token type (or make our own) if we want to, but there is probably no need. More info.

POST

/oauth2/token

or

/oauth2/token/refresh

Called by a client to refresh an authentication token

Body:

OAuth2AuthorizationCodeRefreshTokenRequest

grant_type: String (always "refresh_token" for this call)

refresh_token: String

client_id: Unique

client_secret: String

Body:

OAuth2AccessToken

access_token: String

token_type: String ("Bearer")

expires_in: Integer (seconds)

refresh_token: String


GET

/oauth2/token/introspect

or

/oauth2/token/info

Clients can determine if an authentication token is valid (and get scope, if it is opaque in the token)

Body:

OAuth2TokenIntrospectionRequest

token: String

client_id: Unique

client_secret: String

Body:

OAuth2TokenIntrospectionResponse

active: Boolean

client_id: Unique

username: String (principal of user who authorized)

exp: Date (seconds until expiration)

scope: String

We must have this if we decide to not include scope with the access token
POST/oauth2/revoke

A logged in user can revoke OAuth2 client access using this method.

OAuth2RevokeRequest

client_id: unique

Is there a need for more granularity?

None

Revoking access not in the OAuth2 spec but allowing users to revoke client access may be important.

...

The administrative port should not be exposed to public internet traffic. If you want to expose certain endpoints, such as the /clients endpoint for OpenID Connect Dynamic Client Registry, you can do so but you need to properly secure these endpoints with an API Gateway or Authorization Proxy. 

Do we need this?

Spring Security

Most documentation/blog posts on Spring Security do not refer to our use case. Some posts refer to Spring Security OAuth 2, which is in "maintenance mode" and does not support OIDC. Many posts also instruct using OAuth2/OIDC as a client (we wish to act as a provider).

https://spring.io/blog/2018/01/30/next-generation-oauth-2-0-support-with-spring-securityWhen researching Spring OAuth support, one must be careful to discern between the core Spring Security module (in which OAuth2 implementation is currently in progress in version 5), and the Spring Security OAuth module (which is in "maintenance mode" (which does not support OIDC, is not receiving feature updates, and I imagine is likely to be deprecated some time after Spring Security 5 is feature-complete).

This blog post outlines plans to implement OAuth2 in future versions of Spring with a high-level roadmap.

I think this uses the old version of Spring Security:

...