Skip to content

internal.authentication

orciument edited this page Nov 16, 2024 · 1 revision

[!INFO] This document deals with the Oauth authentication used to restrict access to the backend api, which is used in the fronend application. The Oauth Authentication that is done with twitch and other services is not discussed here, as we are the client and not the ressource server in that scenario.

Warning

You can disable Authentication on all Endpoints by Setting the ENV disableAllAuth to true. This will however remove all checks and make every endpoint (this includes POST, PUT, PATCH, DELETE) public for everyone without any authentication or authorization. Only use this for testing purposes!

Authentication

Authentication of all endpoints is done with an Twitch access token obtained via Twitch OAuth Implicit Grant flow as specified in RFC OAuth 2.0.

Communication Flow

In the language of the RFC, the involved roles for our specific use case are:

  • Ressource Owner: End-User/Panel-User/Moderator (as the person that owns the shared information, the account information)
  • Authorization Server: The Server that issues access tokens to the client, and at which an access token can be validated
  • Client: The Frontend (the application that needs to authenticate itself, and the user to the Ressource Server that serves the requests), in our case it is ECMAScript in the browser (user-agent)
  • Ressource Server: The Backend (as the server that needs to authenticate (and authorize) requests made to it by other clients)

Important

A separate Client (from the backend oauth used to read the chat) is registered with twitch, because the client app (the frontend application inside the users browser) cannot keep an application secret hidden from the enduser, and other applications, and is therefor needs to be a "public client". RFC - Client Types

sequenceDiagram
	participant AS as Authorization Server
	participant C as Client
	participant RS as Ressource Server
	C->>AS: redirect user to twitch Auth/login page
	AS->>C: redirect user with access token back to client url
	C->>C: extract access token, and store for reuse
	C->>RS: request Ressource with access token
	RS-->>AS: validate access token
	AS-->>RS: userId of token holder
	RS->>C: server request resonse
Loading

The AccessToken is passed to the backend via the Token header. The Backend Server the validates it via the twitch id.twitch.tv/oauth2/validate endpoint. The returned username and userId is then used to authorize the request if the user id is supposed to have access to the panel and api resources.

If a validation is not successful, a error will be returned to the requesting party. This will require the sender to get a new accessToken. This does not necessarily mean that user input is required. Some times it is enough to trigger a new implicit grant flow, without the user needing to reauthorize the application. What conditions trigger reauthorization is entirely up to twitch and we have no Control over that.

Response Codes

List of response codes related to authentication and reasons for returning theses codes:

  • 500 - If the token Header is missing
  • 401 - If the access token could not be validated with twitch (token is invalid)
  • 403 - The access token was valid, but the user is not allowed to access the API Ressource

Sessions

The access token is not validated with Twitch on every request. Because of the increased latency that every request would experience, if we would always make a HTTP request to twitch, until we start responding to the request. Instead after the first successful validation a session is created and saved for this specific accessToken and userAgent String (from the browser). If the same accessToken is used with the same userAgent again, the request is accepted.

A Session automatically times out after 15min. On the next request a validation of the accessToken with the twitch Servers will be performed.

Session Management is completely transparent to the client application. Besides increased latency the client does not notice a timed out session at all, and does not need to do anything.

Authorization

After Authentication, the userId is checked for if the twitch user is allowed to have panel access. This is done via the paneluser database table. This table does not hold any authentication or authorization related data, and is only for general account information and preferences.

User Management API

The list of users allowed to access the panel can be modified by any user granted access to the panel. All of the following endpoints are also Authenticated.

Get Panel User List

Get list of all users with panel access GET /panelAccounts Reponse: Json, list of Json Object with username, userId, and accountCreationTime as unix epoch millis.

[
  {
    "username": "TEST_USER",
    "userId": "923928934893489",
    "accountCreationTime": 1730760781627
  }
]

The Twitch User ID consists of only numbers, but is to be treated as an opaque string id without any pattern.

Adding Panel Users

A new Panel User can be added via the username. The username is then converted into the twitch userId and then a new panel user (with defaults) is created and saved POST /panelAccounts Body: the (single) twitch username plain as a string without any special encoding

Remove a Panel User

Delete a (Twitch) user from the list of users with panel access. POST /deleteAllSessions Body: the (single) twitch userId plain as a string without any special encoding

Delete Sessions for one user

Close all sessions of the User associated with this accessToken, all access tokens need to be revalidated POST /deleteUserSessions

Delete All Sessions for all Users

Close all sessions of any user, all access tokens need to be revalidated POST /deleteAllSessions

Overwrite allowed panel users

The list of allowed users can be overridden via the application.properties config. This is useful for setup or as a fallback mechanism.

The new list can be supplied via the allowedPanelUsers key. The value needs to be a ', ' separated list of twitch usernames. This list is then converted into new or existing panel user accounts with twitch userIds.

This new list becomes the active list when the key overwritePanelUsers is set to true. If this is set, all users not in the allowedPanelUsers list lose their panel access, even if they have an account saved in the db.

Example:

allowedPanelUsers=userName1, testUser3
overwritePanelUsers=true

Usage

Creating an Authenticated Client

  1. Create a new Client with twitch on dev.twitch.tv
    1. Select "public client" because the browser cannot keep an client secret
    2. add all your possible redirect urls
    3. (if we would use the same client app, the access token used in the backend chat, and the login, would likely collide and invalidate each other, for the broadcaster, and the chatbot account)
  2. Use Twitch Implicit Grant Flow (not OIDC version) for authentication
    1. create the authorisation url to authorize the app with the users twitch account
      • set response_type to token
      • use the twitch client id
      • set scopes to scopes= (empty, no scopes needed for token validation)
      • set redirect_uri to the url of the panels oauth result page
      • set a random string as state, and save this state for later
    2. redirect the user to this twitch authorization page
    3. on redirect from twitch, remove access token from url, check if the state parameter is the same, and display error page on failure
    4. redirect back to the home page of the bot, and send the access token on every request to the backend bot
  3. If the backend returns a 401, the access token is no longer valid, a new access token needs to be requested by redirecting the user to the authorization page again

Using Authenticated Endpoints

To access an authenticated endpoint, a valid twitch access token needs to be set as the value of the token header.

Setting up authentication on a new Bot Instance

  1. Create a new Client with twitch on dev.twitch.tv
    1. Select "public client" because the browser cannot keep an client secret
    2. add all your possible redirect urls
    3. (if we would use the same client app, the access token used in the backend chat, and the login, would likely collide and invalidate each other, for the broadcaster, and the chatbot account)
  2. Set the TWICH_CLIENT_ID in the frontend .env config
  3. Set your Twitch username in the panel user overwrite list of the backend, and enable overwrite. This ensures access for the first initial setup. The Overwrite mode needs to be disabled after initial setup.
Clone this wiki locally