OpenId Connect Authentication with Authorisation Code Flow
We strongly recommend the use of standardized and validated client libraries from you application code. Security is very difficult to get correct and this article will just show a simplified minimal implementation of the authentication of a user with OpenId Connect (OIDC), more in the purpose to educate the basics than showing production ready code.
Initiating user authentication
The application will initiate a user authentication by re-directing the browser to the authorization endpoint of the Identity Provider (IdP, in this case Authway). The re-direct must be an OIDC authentication request message. Here is an example of the re-direct by the application:
HTTP/1.1 302 Found
Location: https://YOURINSTANCE.irmciam.se/connect/authorize?
client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
&response_type=code
&scope=openid
&state=YOUR_STATE
Explanation of the request parameters in the example:
- client_id: The application (Client) identifier in Authway. This identifier is created when the application is registered in Authway.
- redirect_uri: The callback URI where the application want to retrieve the authentication response. This URI is validated by Authway and it must be an exact match of a registered redirect URI.
- response_type: Set to
code
to indicate that it is the authorisation code flow that should be used. - scope: Used to specify the requested authorisation in OAuth.
openid
indicates a request for OIDC authentication and a ID token. More scopes can be supplied to indicate what information should be included in the ID token. - state: Value set by the application to keep state between the request and the callback.
There are more parameters that can be used.
At the Idp the user will be prompted to sign-in, if that is not already the case. After the Idp has successfully authenticated the user it will call the application redirect_uri
with an authorization code (or an error code if Idp fails).
HTTP/1.1 302 Found
Location: https://client.example.org/callback?
code=A_CODE_ISSUED_BY_IDP
&state=YOUR_STATE
The application must validate the state
parameter and if successful continue to exchange the code
for the ID token.
Exchange code for ID token
The retrieved code
is meaningless to the application and must be exchanged for an ID token by making a back-channel call to the Idp. By making this in a back-channel the client can be validated, so that the Idp is only revealing tokens to trusted applications, and the ID token is never exposed to the browser (which is more secure).
The code can be exchanged at the token endpoint:
POST /connect/token HTTP/1.1
Host: YOURINSTANCE.irmciam.se
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
grant_type=authorization_code
&code=A_CODE_ISSUED_BY_IDP
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
Client ID and secret can be passed in the Authorization
header or as client_id
and client_secret
parameters in the request body. The form-encoded parameters should include a repeated redirect_uri
and the retreved code
from the response after the successful authentication of the user.
If the Idp handles the request successfully it will return a JSON object with the ID token, an access token and optionally a refresh token together with expiration information.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"id_token": "A_JWT_TOKEN",
"access_token": "AN_ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
}
The ID token should be validated by the application before it is accepted.