Skip to content

Customer Authentication #120

@nickevansuk

Description

@nickevansuk

Proposer

MCRactive, Westminster City Council, Everyone Active, Gladstone, Playwaze, SportBuddy, Deuce, Bristol City Council, London Sport, Played, Sport:80

Reference email threads: 1, 2, 3

Use Case

As an existing member of Everyone Active, I want to be able to use my membership through MCRactive, Active Westminster, Deuce, and SportBuddy to find and book activities and facilities, ensuring that I pay prices that include any membership discounts (include discounted to "free" if appropriate).

This is particularly useful to the activity provider for retention-based use cases (e.g. brokers that provide health tracking or motivational tools).

Why is this needed?

The existing booking specification includes a recommendation for "11.7.3 Customer level authentication”, but no mechanism to allow these details to be used as part of the booking flows, except for an example extension which does not include enough information to fully specify an implementation.

User journey

  1. An anonymous Customer using a Broker is prompted to choose between "Guest Checkout" and "Use my existing membership".

    • To ensure this journey is smooth, the Broker will need access to the Customer's e-mail address to send e-mail notifications.
  2. A logged-in Customer using a Broker is prompted to "Connect my existing membership" so that subsequent purchases can make use of that membership where relevant.

    • Although as per 16.6.1 Simplified VAT invoices a customer's details are not required on the VAT invoice for the simple case, it may be useful to have basic personal data (e.g. e-mail address) available to the Broker for the purposes of accurate record keeping - i.e. so that the VAT invoices created by the Broker are not incorrectly attributed.

Proposal

Open Booking API 1.0 CR section 11.7.3 currently recommends the popular standard OpenID Connect for Customer Authentication. The OpenID Connect flow is the same flow that is used for "Login with Facebook" or "Login with Google" that many users are already familiar with:

Untitled drawing (5)

This proposal recommends building on this existing recommendation with a mechanism to allow this authenticated Customer to make a booking.

Model additions

This can be achieved with minor updates to the existing specification, via the introduction of a new AuthenticatedPerson type that subclasses Person. This AuthenticatedPerson can be used as both a customer and attendee, in place of a "guest" Person, and alongside other "guest" Persons.

The AuthenticatedPerson type includes an additional accessToken property, which is used to demonstrate the Broker's authorization to book on behalf of the Customer, and also to identify that Customer. Following Open ID Connect conventions, a accessToken is usually short lived (e.g. 1-2 hours).

The AuthenticatedPerson must be valid against the OrderItem for which it is used (if attendee), or valid against all OrderItems (if customer). If this is not the case, a specific subclass of OpenBookingError should be returned against the OrderItem, or whole Order, respectively.

Classes

Class subClasses Description
oa:AuthenticatedPerson schema:Person Represents a Person that has authenticated with the Seller, and granted access to the Broker to book on their behalf.

Properties

(Class) Property Expected Type Description
(oa:AuthenticatedPerson)
oa:accessToken
schema:Text An access token that verifies the Broker's authorisation to book on behalf of a specific Customer.

Restricted access to Booking System personal data

To inform the Customer that their linked account has been used to create the Order, for the purposes of audit and attribution, to take payment, and to allow for e-mail notifications to be sent in user journey (1) a minimal set of fields of personal data are required.

The proposal recommends that the customer's e-mail (and membership identifier, if different from e-mail) MUST be supplied in the response to C1 , C2 , and B within AuthenticatedPerson, using email and identifier properties as appropriate. Additional properties of Person MAY also be supplied, such as givenName and familyName. The OpenID Connect flow will capture explicit consent from the customer to share this data, which mitigates any concerns around GDPR.

To ensure minimum exposure of the personal data that the Customer has agreed to share, the accessToken MUST be either an opaque token (that contains no personal data) or an encrypted JWT (that contains only the Customer's unique identifier, and is encrypted). If an encrypted JWT is used, the accessToken MUST NOT be stored for longer than its expiry (typically 1-2 days).

In order to ensure that the personal data received is not used outside of the bounds of providing the service, this personal data MUST NOT be used for any other purpose outside of generating invoices, VAT receipts and notifications relating specifically to that unique Order. For the avoidance of doubt, it MUST NOT be used for creation of an account in the Broker, or for other communication outside of those required to service that specific Order, without the Seller's explicit consent (and Customer's explicit consent, where GDPR requires it).

Security

Due to the ability for B to return personal data from the Booking System, which relies on the accessToken being supplied from the results of user authentication, the code flow of Open ID Connect is strongly recommended, and the implicit flow RFC6749 MUST NOT be used (ref).

Offline access

In order to allow the Broker to make bookings without requiring continual re-authentication of the Customer, Offline Access MUST be permitted, where the user has explicitly consented (as per OpenID Connect spec), using a refresh_token.

Pricing

The prices returned for the Offers requested by the Broker on behalf of the Customer MUST match the expectations of the Customer based on any existing membership with the Seller.

Broker contract with Booking System

Currently "The Broker MUST call C1 (without Customer details)", however with this proposal the Broker MAY supply the AuthenticatedPerson at C1 , if known, to have C1 return the correct pricing.

Open Questions and Design Decisions

Access to additional personal data

It is possible for the specification to recommend a means for Brokers to access additional personal data about the Customer, via the OpenID Connect /userinfo endpoint of the Booking System. A Booking System MAY make a number of claims available to the Broker via this mechanism within the Open ID Connect specification.

Do we want to recommend use of /userinfo within the Open Booking API?

To keep the core of Open Booking API cleanly separated from the authentication approach, to adopt a privacy-first approach, and to ensure that the API remains applicable to the broadest number of use cases - the proposal currently recommends that it is better to not include reference to /userinfo specifically in the Open Booking API specification, and certainly not to require it for the flow.

OpenID Connect id_token vs access_token

In the OpenID Connect specification, the intended audience of the id_token is the client application (Broker), where the intended audience of the access_token is the resource server (Booking System). The token for this use case is primarily intended to be received by the Booking System, to provide access to book on the user's behalf. Hence the access_token is the relevant token to use here. The access_token also contains the minimum personally identifiable information by default.

OpenID Connect id_token vs /userinfo via access_token

Within OpenID Connect there are two standard options for getting the authenticated user's details: the OpenID Connect (OIDC) specification includes:

  • ID Token
    • Contains the information at the time the authentication took place, which may be the last time a refresh_token was used.
    • Typically "one-time usage", and for example in Auth0 by default is valid for 36000 seconds (10 hours).
    • Contains user profile attributes, is consumed by an Application (Broker) and typically used for user interface display.
  • /userinfo endpoint accessible via an access_token
    • Provides an updated view of the user information.
    • Can be accessed for the lifetime of the access_token, which can be extended via the refresh_token.

Due to the possibility of token substitution attacks, the /userinfo response is not guaranteed to be about the End-User identified by the sub (subject) element of the ID Token. "The sub Claim in the UserInfo Response MUST be verified to exactly match the sub Claim in the ID Token; if they do not match, the UserInfo Response values MUST NOT be used.". Hence the id_token is required even with access to /userinfo.

As above, perhaps it is better to not recommend either of the above specifically, and not to require them in the flow.

Example

C1 , C2 and B request:

  "customer": {
    "@type": "AuthenticatedPerson",
    "accessToken": "SlAV32hkKG"
  },

C1 , C2 and B response:

  "customer": {
    "@type": "AuthenticatedPerson",
    "identifier": "314251861",
    "email": "geoffcapes@example.com",
    "givenName": "Geoff",
    "familyName": "Capes"
  },

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions