authorization-endpoint
This article is a stub. You can help the IndieWeb wiki by expanding it.
An authorization endpoint is an HTTP endpoint that micropub and IndieAuth clients can use to identify a user or obtain an authorization code (which is then later exchanged for an access token) to be able to post to their website.
Contents
Authorization Endpoint Flows
Flows Required by the Spec
From a client app’s point of view (and as required by the indieauth spec), an authorization endpoint must support the following request flows:
- A GET request (sent from the user’s browser via a redirect) with a query string containing authorization code request parameters. The response to this request is shown to the user, and is out of scope of the spec, but if successful it should result in the user being redirected to the
redirect_uri
parameter withcode
andstate
query string parameters. - A POST request to exchange an authorization code for profile information. Should return a JSON response body with either an error or a
me
response, optionally with profile information.
In practise, the authorization endpoint typically has to handle authenticating the user, presenting a consent screen, and handling the consent screen form submission, before redirecting to the client app’s redirect_uri
. A common way to handle this is as follows:
- authorization request: a GET request which the user was redirected to from their client app, with code request parameters in the query string.
- If the request is not authenticated (i.e. the user is currently logged out): perform authentication (usually by redirecting to a login page) and restart the flow.
- If the request is authenticated (i.e. the user is currently logged in): validate the code request parameters, and return either an error response if invalid, or a consent screen response if valid.
- consent form submission: a POST request containing data submitted from the consent screen form. MUST be CSRF-protected.
- If the submitted data is invalid, return an error response
- If the submitted data is valid, build an authorization code, and return a 302 Redirect response to the
redirect_uri
, withstate
andcode
query parameters.
- auth code exchange for profile information: a POST request with auth code which results in a JSON response. Similar to the token endpoint flow. MUST NOT be CSRF-protected.
- If the provided code, verifier and client ID are valid, return a JSON response containing
{"me": "https://me.example.com"}
and optionally profile information. - If the request was invalid, return a JSON OAuth2 error response
- If the provided code, verifier and client ID are valid, return a JSON response containing
Creating an Authorization Endpoint
⚠️ This section on the wiki might be outdated.
For the most up-to-date information on IndieAuth authorization endpoints, see the IndieAuth Living Standard. One post of particular interest: IndieAuth Spec Updates 2020.
An authorization endpoint must be able to both generate authorization codes as well as verify the authorization codes it issues.
Web Sign-In Form
The site contains a web sign-in form prompting the user to enter their personal web address to sign in. Upon submitting the form, the site begins the auth process by discovering the user's auth endpoint, e.g.:
See http://microformats.org/wiki/web-sign-in for more UI details / possibilities.
Discovery
The web application checks the user's website for a link with a rel-value of "authorization_endpoint":
<link rel="authorization_endpoint" href="https://indieauth.example.org/">
Use this URL as endpoint for processing.
Authorization Endpoint
To start the sign-in flow, the user's browser will be redirected to their authorization endpoint, with additional parameters in the query string.
Directing the user's browser to the auth endpoint is usually done via a HTTP Location
header, but can optionally be an <a>
tag with an href set to the authorization URL.
Request
Note: Values are shown with extra linebreaks and without URL encoding for readability.
https://auth.example.org/auth ?me=https://aaronparecki.com/ &client_id=https://webapp.example.org/ &redirect_uri=https://webapp.example.org/auth/callback &state=1234567890 &response_type=id
Parameters:
- me
- Full URI of the user's homepage (not required, as it's not needed for one-user sites [1])
- client_id
- Full URI of the application's/website's home page. Used to identify the application. An authorization endpoint may show the application's icon and title to the user during the auth process.
- redirect_uri
- Full URI to redirect back to when the login process is finished
- Needs to be registered with a <link> tag on the client_id [2]
- state
- A random value the app makes up, unique per request. The authorization server just passes it back to the app.
- Optional. Auth endpoints MUST support them, though.
- response_type
-
id (identification only) or code (identification + authorization) - Optional. Defaults to id. Always code, but servers should treat id as code for backwards compatibility.
- scope
- For authorization, the scope contains a space-separated list of scopes that the web application requests permission for, e.g. "create". Multiple values are supported, e.g. create delete
Redirect URI verification
- why is redirect_uri separate from state?
- the callback URL shouldn't be dynamic per request so that callback URLs can be registered. "state" is allowed to vary per request
- why should callback urls be registered?
- without registration it's easier to perform a redirect attack. more background here: http://tools.ietf.org/html/rfc6749#section-3.1.2.2
- how does the client website register the callback at the server?
- the client publishes its registered redirect URLs on its web page with a <link> tag
- since client IDs are always URLs, it's all discoverable that way
- for client_id https://example.com/ a server can find its valid redirect URIs by looking for
- <link rel="redirect_uri" href="https://example.com/callback">
- at example.com
- described in more detail at https://indieauth.spec.indieweb.org/#redirect-url
Verify the user
The authorization server should present an interface describing the request being made. It must indicate:
- The client_id making the request
- Optionally the server can include the name and logo if an h-card is found on the client_id URL.
- The scope if authorization is requested.
See Consent Screen for more UI examples.
TODO: Example. See h-app.
Redirect to web application
The authorization server presents the request information to the user, and if they approve, generates an authorization code and redirects the user to the redirect URI specified.
HTTP/1.1 302 Found Location: https://webapp.example.org/auth/callback ?code=xxxxxxxx &state=1234567890
Parameters:
- code
- Authorization code
- state
- State variable sent by the web application
Auth code verification
For the sign-in flow, the web application will query the authorization endpoint to verify the auth code it received. The client makes a POST request to the authorization server with the following values:
POST https://auth.example.org/auth Content-type: application/x-www-form-urlencoded code=xxxxxxxx &redirect_uri=https://webapp.example.org/auth/callback &client_id=https://webapp.example.org/
After the authorization server verifies that redirect_uri, client_id match the code given, the response will include the "me" value indicating the URL of the user who signed in. The response content-type must be application/json
.
HTTP/1.1 200 OK Content-Type: application/json { "me": "https://aaronparecki.com/" "profile": { "name": "Aaron Parecki", "url": "https://aaronparecki.com/", "photo": "https://aaronparecki.com/images/profile.jpg", "email": "aaron@parecki.com" } }
Parameters:
- me
- Full URI of the user's homepage
- This may be different from the me parameter that the user originally entered, but MUST be on the same domain.
- profile
- profile information, included if scope "profile" or "email" was requested. [3]
Use by Token Endpoints
When used in the flow for obtaining an access token that can create posts using Micropub, the token endpoint will be making the request to verify the authorization code, rather than the client. In this case, the client will make the request described above to the token endpoint instead. If the token endpoint and authorization endpoint are part of the same software, then of course the token endpoint can verify the authorization code using a proprietary method, such as looking up the code from the same database that the authorization endpoint stored it in.
IndieWeb examples
The following people have an authorization endpoint on their own domain:
-
Aaron Parecki at https://aaronparecki.com/auth as of 2016-04-13
-
Sebastiaan Andeweg at https://seblog.nl/auth as of IndieWebWeek 2017 in Düsseldorf and Nürnberg.
-
Martijn van der Ven at http://vanderven.se/martijn/auth/ as of 2017-06-30, selfdogfooding with selfauth.
-
Jeena Paradies at https://jeena.net/indieauth as of IndieWebCamp 2017 in Berlin
Other Examples
Software implementing the authorization endpoint spec
Using an Authorization Service
You can use an existing authorization service such as indieauth.com if you don't want to build your own authorization service.
Open Source Authorization Endpoints
- indieauth.com - written in Ruby, the software that runs indieauth.com
- selfauth - written in PHP
- befitting-price a node.js authorization server on Glitch.com
FAQ
Why are auth codes verified with a POST instead of a GET
If auth codes are sent as a GET request in the query string, they may leak to log files or the HTTP "referer". The decision was made by the OAuth 2.0 working group to use POST requests and the HTTP Authorization header for sending these sensitive tokens and auth codes.
Can the authorization codes be used more than once
No, the authorization code must not be used more than once. If the code is used more than once, the authorization server must deny the request.[4] A maximum lifetime of 10 minutes is recommended for the authorization codes, although many implementations have a lifetime of 30-60 seconds.
Can I add additional parameters for the authorization request
No, but you can use the "state" parameter to encode or reference additional application-specific parameters. The state parameter will be passed around and was designed for this purpose as well as to prevent CSRF attacks.
Does the auth server have to support the state parameter
Yes, the state parameter can be used by the client to maintain state between the request and the callback, so the auth server must support it. It is also used to prevent CSRF attacks.
What is IndieAuth: authorization_endpoint
Previously, there was a recommendation to have authorization endpoints return an HTTP header IndieAuth: authorization_endpoint
. It was thought that this was necessary in order to avoid false positive matching of endpoints on indieauth.com. After some thought, this is not a necessary step, so this recommendation has been dropped.