Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
projects:member_portal:oauth [2025/10/13 10:27] samp20projects:member_portal:oauth [2025/10/13 12:14] (current) samp20
Line 5: Line 5:
 ^ Column ^ Type ^ Obtained from ^ Description ^ ^ Column ^ Type ^ Obtained from ^ Description ^
 | id | UUID | Generated | ID to keep track of the request | | id | UUID | Generated | ID to keep track of the request |
-secret | str | Generated | Secret stored in a flow cookie |+token_hash | str | Generated | Hash of a secret token stored in a flow cookie |
 | session_id | Optional FK | Logged in session | Associated login session | | session_id | Optional FK | Logged in session | Associated login session |
 | client_id | FK | Query string | The OAuth client sending this request | | client_id | FK | Query string | The OAuth client sending this request |
Line 16: Line 16:
 | code_challenge | str | Query string | PKCE challenge | | code_challenge | str | Query string | PKCE challenge |
 | code_challenge_method | str | Query string | PKCE method | | code_challenge_method | str | Query string | PKCE method |
 +
 +===== Generating the response =====
 +
 +The response is dependent on the ''response_type'' field. This is a space separated set with various options:
 +  * ''code'': a code to be submitted to the Token endpoint to obtain other information.
 +  * ''token'': an access token.
 +  * ''id_token'': an OpenID ID token.
 +
 +The ''response_mode'' is determined implicitly based on the ''response_type''. This can take the following values:
 +  * ''query'': the response is returned in the query string.
 +  * ''fragment'': the response is returned in the URL fragment (stuff after the ''#'' symbol).
 +
 +The ''query'' mode is used when only the ''code'' is being requested, otherwise the URL fragment is used. Most of the time clients will only be requesting a code.
 +
 +==== The authorization code ====
 +
 +This is a short lived code that can be submitted to the Authorization endpoint in exchange for ID and access tokens. The ''code_challenge'' may also be used at this point using the [[https://www.rfc-editor.org/rfc/rfc7636|PKCE standard]]
 +
 +==== The ID token ====
 +
 +The ID token shall be returned if the ''openid'' scope was requested. These are the claims we plan to support:
 +
 +^ Claim ^ Required ^ Description ^ Obtained from ^
 +| iss | REQUIRED | Issuer identtifier. | Portal base URL. |
 +| sub | REQUIRED | Subject identifier. | User from the ''session_id''. |
 +| aud | REQUIRED | Audience(s) the ID token is intended for. | ''client_id''. |
 +| exp | REQUIRED | Token expiration time. | Per-client configuration. |
 +| iat | REQUIRED | When the token was issued. | Current time when the token is generated. |
 +| auth_time | OPTIONAL (unless requested through ''max_age'' query parameter) | Time when end user authentication occured. | Most recent timestamp in the session's last_xx_auth fields. |
 +| nonce | OPTIONAL unless present in request | String value to associate client session with ID token and to mitigate replay attacks. | Request ''nonce''. |
 +| acr | OPTIONAL unless requested by ''acr_values'' | Authentication context class (how "strong" the authentication was). | [[projects:member_portal:session|Session]] authentication level. |
 +| amr | OPTIONAL | Authentication methods. | [[projects:member_portal:session|Session]] authentication methods based on ''last_xx_auth'' fields. May be filtered based on ''max_age'' if present. |
 +
 +Note that only ''azp'' is missing from  the OpenID core spec as we don't plan to use any extensions to the spec.
 +
 +==== The access and refresh tokens ====
 +
 +While the Hackspace services might be spread across multiple servers, we will use a single logical API approach for our access tokens. This means that all scopes will be part of a single global namespace. For example ''email:send'' might allow sending emails via and email service.
 +
 +The Access token will be a transparent signed JWT with the following claims:
 +
 +^ Claim ^ Description ^ Obtained from ^
 +| iss | Issuer of the token | The portal base URL |
 +| sub | Subject | The user or client subject depending on whether it was a Authorization Code flow, or Client Credentials |
 +| aud | The global scope namespace | Configuration value e.g. ''hackspace'' |
 +| exp | Expiry | Relatively short configuration value e.g. 1 hour |
 +| iat | Issued at | Timestamp when the token was created |
 +| jti | Unique identifier | Randomly generated |
 +| client_id | Client identifier | The OAuth client that requested the token |
 +| scope | Granted scopes | Requested scopes filtered by the user's permissions |
 +
 +The refresh token will be an opaque token with a corresponding table containing the same information as the access token. The table may also contain a reference to the user's session ID so the token can be revoked if the session ends.
  • projects/member_portal/oauth.1760351225
  • Last modified: 8 weeks ago
  • by samp20