Skip to content

Authentication

Sandeep Puthanveetil Satheesan edited this page Oct 19, 2022 · 8 revisions

Authentication

The Core BB includes an auth sub-service that provides the mechanisms used to authenticate and authorize users throughout the Rokwire ecosystem.

API Keys

Each client Application has an associated API key. To access any of the authentication endpoints this API key must be provided to ensure that the request is coming from a valid client.

Note: These API keys should be used only when sending requests to the Core BB. Other Rokwire Building Blocks should not be storing these API keys directly, as this makes managing and updating them complicated. Instead, the client should use one of the Auth Flows to retrieve an access token which can be sent to other BBs for authorization purposes.

While API keys should be protected and kept secure within client applications, an API key alone is not sufficient to be considered a form of authentication. In order to ensure that a request was sent by an entity with the appropriate authorization, some form of User Authentication or Service Account Authentication must take place. To learn more, see the Anonymous Flow section.

User Authentication

There are several supported mechanisms that allow users to authenticate with the Core BB.

Email

Email authentication can be performed using an email address and password.

Email Auth Configuration

In order to allow the system to send emails for Email Verification and Password Reset, the following environment variables must be configured on the Core BB:

  • ROKWIRE_CORE_SMTP_HOST: The host URL of the SMTP server
  • ROKWIRE_CORE_SMTP_PORT: The port emails should be sent to on the SMTP server
  • ROKWIRE_CORE_SMTP_USER: The user name to be used when connecting to the SMTP server
  • ROKWIRE_CORE_SMTP_PASSWORD: The password to be used when connecting to the SMTP server
  • ROKWIRE_CORE_SMTP_EMAIL_FROM: The email address to be displayed to the user as the "from" address in the verification emails.

Email Sign In

To sign into an existing account, a request must be sent to the /services/auth/login endpoint with the following creds and params data in the body.

creds:

  • email (string) - The users email address associated with the account
  • password (string) - The password associated with the provided email

params:

  • sign_up (boolean) - A flag indicating whether this request is intended as a sign-up (true) or sign-in (false) operation. If the sign_up param is not specified, the Core BB will check if the credentials match an existing account and automatically attempt to sign in if one is found, or sign up if not.

Below is an example of these elements for a sign-in request:

{
	"auth_type": "email",
	...
	"creds": {
		"email": "[email protected]", 
		"password": "test12345"
	},
	"params":{
		"sign_up": false
	},
	...
}

If the credentials are verified successfully, the account data and tokens will be returned.

Email Sign Up

To sign up for a new account using the email auth type, a request must be sent to the /services/auth/login endpoint with the following creds and params data in the body.

creds:

  • email (string) - The users email address to be associated with the new account
  • password (string) - The password to be associated with the provided email

params:

  • sign_up (boolean) - A flag indicating whether this request is intended as a sign-up (true) or sign-in (false) operation. If the sign_up param is not specified, the Core BB will check if the credentials match an existing account and automatically attempt to sign in if one is found, or sign up if not.
  • confirm_password - The contents of the password confirmation field to ensure that the user did not mistype their password. This field must match the password fields in the creds object. Ideally, this match should be confirmed locally on the client as well to avoid unnecessary requests.

Below is an example of these elements for a sign-up request:

{
	"auth_type": "email",
	...
	"creds": {
		"email": "[email protected]", 
		"password": "test12345"
	},
	"params":{
		"sign_up": true,
		"confirm_password": "test12345"
	},
	...
}

Once the sign up request completes successfully, the user must perform Email Verification.

Email Verification

Email verification can (and should) be performed after a user signs up before they are able to access their account. Enabling this will send the user a verification email after Email Sign Up with a link that they must click before they will be able to login. This link will expire after some time. Once the link expires, a new one will be generated and sent automatically the next time the user attempts to sign in.

To support this feature, the configurations described in Email Auth Configuration must be completed.

Note: While highly discouraged in a production system, email verification may be disabled by setting the "verify_email" param to false on the email auth type. This will allow users to sign up and login with this auth type without verifying their email address.

Password Reset

Users may reset their password by sending a request to the /services/auth/credential/forgot/initiate endpoint. This will send a password reset email to the specified email address with a link that will direct them to a reset password form.

To support this feature, the configurations described in Email Auth Configuration must be completed.

Warning: Enabling the password reset email system does reduce the security of the email authentication. While it is convenient for users to be able to reset forgotten passwords, it does allow anyone with access to the registered email to change this password at any time.

Phone

Phone authentication can be performed through SMS using Twilio Verify. Phone authentication can be performed the same way whether or not the user already has an existing account using the Phone Login flow.

Warning: Phone authentication is less secure than the other methods since only a code delivered by SMS (ie. no password) is required to authenticate successfully. SMS has many known security issues including lack of encryption, vulnerability to phishing, potential for SIM swapping, and others.

Phone Auth Configuration

In order to enable phone authentication, the following environment variables must be configured on the Core BB:

  • ROKWIRE_CORE_AUTH_TWILIO_ACCOUNT_SID: The Twilio account SID
  • ROKWIRE_CORE_AUTH_TWILIO_TOKEN: The Twilio account auth token
  • ROKWIRE_CORE_AUTH_TWILIO_SERVICE_SID: The Twillio Verify service SID

Phone Login

To initiate a login, a request must be sent to the /services/auth/login endpoint with the following creds data in the body.

creds:

  • phone (string) - The users phone number to be used during authentication

Below is an example of these elements for the initiation request:

{
	"auth_type": "phone",
	...
	"creds": {
		"phone": "+12223334444"
	},
	...
}

A verification code will then be sent to the specified phone number via SMS.

To complete the login, a second request must be sent to the /services/auth/login endpoint with the following creds data in the body.

creds:

  • phone (string) - The users phone number to be used during authentication
  • code (string) - The verification code received via SMS

Below is an example of these elements for a verification request:

{
	"auth_type": "phone",
	...
	"creds": {
		"phone": "+12223334444", 
		"code": "123456"
	},
	...
}

If the code is verified successfully, a new account will be created if necessary and the account data and tokens will be returned.

External Authentication Providers

External Authentication Providers are external systems that handle authentication and identity management. These authentication methods are typically used to enable "Single Sign-On" within organizations, which allow users to authenticate into many applications through one standard system and process. Identity Providers can be used to configure the integration with these systems. The Core BB supports the following external authentication protocols.

OpenID Connect (OIDC)

The Core BB provides an OpenID Connect (OIDC) integration to allow organizations to link their existing Single Sign-On (SSO) systems. OIDC authentication can be performed the same way whether or not the user already has an existing account using the OIDC Login flow.

OIDC Configuration

In order to enable an OIDC provider, an Identity Provider must be created and configured for each supported Application Type. The following configurations are available:

Name Key Type Required Description
Host host string true The host URL for the OIDC provider.
Authorization URL authorize_url string false The full URL for the "authorize" endpoint of the OIDC provider. If this is not provided, it will default to {host}/idp/profile/oidc/authorize.
Token URL token_url string false The full URL for the "token" endpoint of the OIDC provider. If this is not provided, it will default to {host}/idp/profile/oidc/token.
User Info URL userinfo_url string false The full URL for the "userinfo" endpoint of the OIDC provider. If this is not provided, it will default to {host}/idp/profile/oidc/userinfo.
Scopes scopes string false Any specific scopes that should be requested from the user.
Use Refresh use_refresh boolean false A flag indicating that the refresh flow should be supported for this OIDC provider. If this is not provided, it will default to false.
Use PKCE use_pkce boolean false A flag indicating that the PKCE Flow should be supported for this OIDC provider. If this is not provided, it will default to false.
Client ID client_id string true The client ID to be used when making requests to the OIDC provider.
Client Secret client_secret string false The client secret to be used when making a "token" request to the OIDC provider.
Authorize Claims authorize_claims string false The claims requested from the OIDC provider to be included in the user's token.
OIDC Login

To login using an OIDC provider, a request should first be made to the /services/auth/login-url endpoint to get a pre-formatted login URL for the specified application. An active redirect_uri that deeplinks back into the client application must be provided in the body. This endpoint may return some params to be stored on the client and sent in subsequent requests along with the login URL.

The client should then direct the user to the login URL to perform login through the configured SSO webpage. Upon successful completion, the user will be directed to the provided redirect URI.

Note: For mobile clients, the login URL should be opened in an external browser. Opening SSO webpages in an embedded web view internal to the application is bad practice, as using these embedded web views makes it trivial for the client to capture user credentials and other private information that the client should not be able to access. Many app stores now have policies against such practices, so doing so may result in rejection or removal during the app review process.

Upon receiving the callback from the SSO page at the redirect URI, the client should next, make a request to the /services/auth/login endpoint with the following creds and params data in the body.

creds: The full redirect request received from the SSO page at the redirect URI. For example, the request may look something like https://redirect.example.com?code=ai324uith8gSEefesEguorgwsf43

params: Any params that were previously saved from the response from the /services/auth/login-url endpoint.

Below is an example of these elements:

{
	"auth_type": "illinois_oidc",
	...
	"creds": "https://redirect.example.com?code=ai324uith8gSEefesEguorgwsf43",
	"params": {
		"redirect_uri": "https://redirect.example.com",
		"pkce_verifier": "w4iuhfq0u43hfq38ghn3gnSFSFiqp3ugnpugnqiprgUGNPINfsdoirpgia"
	},
	...
}

The Core BB will then complete the remainder of the OIDC authentication flow. If it is successful, a new account will be created if necessary and the account data and tokens will be returned.

OIDC Access Tokens

The tokens received from the OIDC provider will also be provided to the client in the params field of the response. Below is an example of this response:

{
	...
	"params": {
		"oidc_token": {
			"id_token": "<OIDC ID TOKEN>",
			"access_token":	"<OIDC ACCESS TOKEN>",
			"refresh_token": "<OIDC REFRESH TOKEN>",
			"token_type": "Bearer"
		}
		...
	},
	...
}

Coming Soon

Support for the following authentication providers is road mapped to be added to the Core BB.

  • Firebase
  • SAML

Linking Authentication Types

Multiple authentication types can be associated with the same user account. For example, a user may initially register for their account using an email and password, then later associate a phone number with that same account. After a new authentication type has been associated, logging in with any of the available auth types will grant access to the same account.

To link a new auth type, the user must login with a previously associated auth type to get an access token for their account. They can then make a request to the services/auth/account/auth-type/link endpoint. Just like when signing up, the user may need to verify the new auth type before they will be able to login with it.

Note: In order to make a request to link a new authentication type, an Authenticated token must be used. This means that the user must be prompted to Sign In again if the current Access Token was generated using the Refresh Flow.

Service Account Authentication

Service Accounts are accounts intended for use by non-human entities, including Building Blocks and Third-Party Services. There are two methods of authenticated that are supported for these accounts.

Service Static Tokens

Static Tokens are opaque tokens that can be used to authenticate with a Service Account. To use a static token, a request must be sent to the /bbs/access-token endpoint. The provided static token will be verified and a Service Access Token will be returned if successful.

Service Signatures

Request Signatures can also be used to authenticate services. To enable this flow, the public key of a Service Key Pair must be registered with the Service Account. The service can then make a request to the /bbs/access-token endpoint signing the request using the process described in Request Signatures.

If the signature on the request matches one of the approved public keys, a Service Access Token will be returned.

Request Signatures

Request Signatures provide a mechanism to authenticate and verify the integrity of a request. The implementation of these signatures supported by the Core BB is based on the HTTP Signatures Draft.

Note: The Auth Library sigauth package implements this signature specification and exposes high level interfaces that can be used to quickly and conveniently sign requests. Using and staying up to date with the Auth Library is the easiest way to ensure your signatures will remain compatible with the Core BB.

Signature String

  • request-line - The request method, URL path, and protocol separated by spaces. For example: POST /core/bbs/access-token HTTP/1.1.
  • host - The "Host" request header
  • date - The "Date" request header
  • digest - The "Digest" request header. This should be set to the base64 encoded SHA-256 digest of the request body. The hashing algorithm used should be specified in this header as well with the SHA-256= prefix. For example, SHA-256=ARyYYhD+nRoqjgYXkSIyHyq87N/bxhIlt50lSW0D9lM=.
  • content-length - The "Content-Length" request header

To construct the Signature String, these headers should be formatted as {header name}: {header value}, then joined by newlines (\n). For example:

POST /core/bbs/access-token HTTP/1.1
host: api.rokwire.illinois.edu
date: Fri, 01 Apr 2022 19:45:31 GMT
digest: SHA-256=ARyYYhD+nRoqjgYXkSIyHyq87N/bxhIlt50lSW0D9lM=
content-length: 141

Signature

This Signature String should then be signed using the private key of the Service Key Pair. The Signature should be computed on a SHA-256 digest of the signature string using the RSA PSS algorithm. The result should then be base64 encoded.

Signature Authorization Header

The Signature Authorization Header must then be constructed using the computed Signature. The Signature Authorization Header contains the following components:

Name Key Type Required Description
Key ID keyId string true The unique ID for the keypair used to sign the request.
Algorithm algorithm string true The algorithm used to sign the request. This should be rsa-sha256.
Headers headers string false The header names to include in the signature string separated by spaces (' ').
Extensions extensions string false Any additional information that should be included for protocol extensions. This field is currently unused by the Core BB.
Signature signature string true The Signature described above.

To construct the Signature Authorization Header, the word "Signature" followed by a space (' '), should be followed by these fields should formatted as {name}="{value}", then joined by commas (,). For example:

Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",headers="request-line host date digest content-length",signature="Base64(RSA-SHA256(signing string))"

Multi-Factor Authentication

The Core BB supports Multi-Factor Authentication (MFA) for user accounts. MFA provides an additional layer of security beyond passwords. This is especially important when protecting sensitive user data and administrative access.

Factors

Most MFA is based on one of the following authentication factors:

  • Something the user knows (knowledge) eg. a password
  • Something the user has (possession) eg. a token, a smartphone
  • Something the user is (inherent), eg. biometrics (fingerprints, eye iris...)

Since the primary form of authentication is often a password (knowledge), an effective MFA method should represent a different factor (ie. possession or an inherent characteristic).

Methods

Several methods of MFA are implemented by the Core BB.

Time-Based One-Time Password (TOTP)

Time-based one-time passwords (TOTP) is a common form of MFA that generates unique numeric passwords that are valid for a certain time period. Users must download a TOTP client application on their device, such as Google Authenticator and Authy. These are just examples of a couple of the many such clients available. These clients operate offline by storing a secret on the device that is used along with the current time to generate the temporary passwords.

Since the secret needed to generate TOTPs is stored only on the user's device, TOTP is considered to represent "something the user has".

Coming Soon

Note: Email and phone multifactor can only be used with when logging in with a different authentication type.

Phone (SMS)

Since text messages are sent to a phone number tied associated with a specific mobile device, SMS is often considered to represent "something the user has".

Warning: While SMS is a common method of MFA, there are several key security concerns that it presents, including lack of encryption, vulnerability to phishing, potential for SIM swapping, and others.

Email

Since all that is needed to access an email account is the account password, an email is considered "something the user knows".

Warning: Since the primary form of authentication often relies on a password which is "something the user knows", emails often cannot be considered "true" MFA. It is also weaker than other methods since it is only as secure as the email itself, which can vary widely.