OpenID


This is the mostly-complete OpenID specification.

Optional fields default to the values given.

This page contains low-level details. For a high-level overview, see OpenID specs.

Document outline:

Overview

The OpenID protocol is an exchange of messages which can operate in either stateless ("dumb mode") or stateful ("smart mode") form over an HTTP or HTTPs connection. All data sent back by Server in response to a Consumer HTTP request are transmitted via the body of the query, like in a regular HTTP request.

A protocol diagram summarising the OpenID protocol, has been kindly provided by Steven J. Murdoch.

The protocol is marked as "version 1.1" in the Perl reference implementation.

Limits

Key-Value Colon/Newline format

Flow

Here is, shortly, the identification process flow which forks depending on whether immediate mode is used.

Common steps

(input sanity checks are omitted)

Flow for a stateless Consumer ("dumb mode")

  1. Consumer builds an "identity check" GET URL request from the OpenID Server URL (checkid_immediate), specifying a return URL. Consumer redirects the User-Agent to the Server.

    • If check failed, Server builds a "failed assertion" GET URL (id_res) from the Consumer-provided return URL, specifying a user setup URL. Server redirects the User-Agent to the Consumer. Consumer takes whatever action it considers appropriate, with the possibility of pointing the User-Agent to the user setup URL.

    • If check succeeded, Server builds a "succeeded assertion" GET URL (id_res) from the Consumer-provided return URL. Server redirects the User-Agent to the Consumer.

  2. Validation step: Consumer requests message authentication (check_authentication via POST) with the stateless assoc_handle.

Flow for a stateful Consumer ("smart mode")

  1. If server is not associated, Consumer requests a shared secret and an association handle. (associate via POST)

  2. Consumer builds an "identity check" GET URL request from the OpenID Server URL (checkid_setup), specifying a return URL. Consumer redirects the User-Agent to the Server. Server proceeds to any necessary steps leading to allowing, denying or failing (not logged in) access to the URL.

    • If check failed because the user declined to share their identity, Server builds a "canceled notification" GET URL (cancel) from the Consumer-provided return URL. Server redirects the User-Agent to the Consumer. Consumer takes note of the process abortion.

    • If check failed because the user is not set up on the Server (e.g. not logged in), Server builds a "failed assertion" GET URL (id_res) from the Consumer-provided return URL. Server redirects the User-Agent to the Consumer. Consumer takes note of the process abortion and generally offers the option to use the Server-provided setup URL.

    • If check succeeded, Server builds a "succeeded assertion" GET URL (id_res) from the Consumer-provided return URL. Server redirects the User-Agent to the Consumer.

  3. Consumer checks if its provided associate handle is valid.

    • If valid, Consumer checks messages signatures using the shared secret associated to the handle.

    • If not valid, Consumer invalidates the previous association and switches to dumb mode with the returned stateless assoc_handle, step "validation".

Association mode (smart mode)

This is the highly recommended mode to consume OpenIDs. Associated information may be reused for a given period of time (once per day/week/month per consumer per server, depending on expiries and server recommendation.)

Association mode 1: Getting an HMAC secret, no Diffie-Hellman (DH) encryption

In this mode, the shared secret is sent by Server as plain text, in Base64 encoding.

consumer --> idserver:

idserver --> consumer: (text/plain ASCII newline-terminated key:value pairs)

secret is the Server function producing a mac_key depending on which assoc_type is used.

Association mode 2: Getting an HMAC secret, encrypted with a DH shared secret

In this mode, the shared secret is sent encrypted with Diffie-Hellman, and encoded in Base64. If the Server does not support DH, they may ignore the DH fields in the request and reply exactly as to a non-DH request.

All integers are represented in big-endian signed two's complement, Base64 encoded. In other words, the "btwoc" function used below is a function that takes a bigint and returns its shortest big-endian two's complement notation.

The Consumer starts by choosing the group parameters:

and produces a public key.

The Consumer public key is X = g ^ x mod p

consumer --> idserver:

If the consumer does not supply either or both of dh_modulus or dh_gen, they default to these integer values:

dh_modulus: 15517289818147369747123225776371553991572480196691540447970779531405\
76293785419175806512274236981889937278161526466314385615958256881888\
89951272158842675419950341258706556549803580104870537681476726513255\
74704076585747929129157233451064324509471500722962109419434978392598\
4760375594985848253359305585439638443

dh_gen: 2

idserver --> consumer: (text/plain ASCII newline-terminated key:value pairs)

The server chooses the Server private key:

and then produces a public key.

The Server DH public key is Y = g ^ y mod p The shared DH secret is thus g ^ xy mod p = (g ^ x) ^ y mod p = (g ^ y) ^ x mod p

The underlying mac_key must be the same length as the output of H, the hash function - in this instance, 160 bits (20 bytes) for SHA1.

Checking identity

Checking identity for computing-enabled Consumers (smart mode)

(Assuming association was correctly done.)

consumer redirect -> UA -> idserver:

If Server-side successful:

idserver redirect -> UA -> consumer:

token_contents in openid.sig are (each key:value pair is newline-terminated)

Then Consumer validates message locally using its mac_key.

If Server-side failed (immediate or "setup+not-logged-in"):

idserver redirect -> UA -> consumer (failed):

If Server-side failed ("setup+user declined"):

idserver redirect -> UA -> consumer (cancelled):

Checking identity for Consumers in limited environments

(aka "dumb consumer mode")

consumer redirect -> UA -> idserver:

If Server-side successful:

idserver redirect -> UA -> consumer:

See above for recreating token_contents.

If Server-side failed (immediate or "setup+not-logged-in"):

idserver redirect -> UA -> consumer (failed):

If Server-side failed ("setup+user declined"):

idserver redirect -> UA -> consumer (cancelled):

Message validation using stateless key

consumer --> idserver:

idserver -> consumer: (newline-terminated key:value pairs)

Server runtime errors, HTTP return codes

This section pertains to protocol/run-time errors, not authentication errors. Authentication errors are defined in the protocol.

References

[Login] Change #68 by OpenID Identitysjmurdoch at 2006-10-06 00:46:31.