IdentityServer4 - Part 1 - The protocols
Oauth 2.0 is an open standard authorization protocol that is being developed by IETF OAuth Working Group. The protocol defines (doesn’t implement) standardized methods to securely authorize web, mobile and desktop applications.
OpenIDConnect – is a layer on top of Oauth2 which merely extends this protocol by adding the user authentication mechanism (in order to have the User context and information available) on top of this protocol.
IdentityServer – is a framework (library) developed to implement the protocol and provide built-in mechanisms to achieve all the flows defined in the Oauth2.0 protocol.
In order to understand the available flows we first have to understand some concepts.
Considering the level on which data is secure on the client, there are 2 types defined:
- these are clients capable of maintaining the confidentiality of their credentials
- They live on the server
Public clients – these are clients incapable of maintaining the confidentiality of their credentials
- They live on browsers, devices
OAuth 2.0 supports several different grants. Grants are ways of retrieving an Access Token. Deciding which one is suited for your case depends mostly on your Client’s type, but other parameters weigh in as well, like the level of trust for the Client, or the experience you want your users to have.In
order to understand the flows we must first have an understanding of the different channels through which the client communicates with the Identity Authority:
- The front channel represents a less secure medium (usually the browser agent). This channel is not as secure as the back channel and, depending on the flow and the app’s limitations, we can entrust it with less information
- The back channel represents a highly secure medium (usually our app server).
The Oauth2.0 protocol defines 4 main flow types:
- Uses the front channel to acquire the authorization_code
- It sends this code to the backchannel.
- The backchannel uses this authorization_code with the client_secret to get the access token
- Uses the front channel only, it has direct access to the access_token.
- Uses backchannel only (less used, exists for compatibility reasons with older applications)
- uses backchannel only (it’s a machine to machine authorization). The backchannel can access a specific api using the client_secret and client_id
- The client_credentials grant is used when applications request an access token to access their own resources, not on behalf of a user
Open Id is a layer on top of OAuth2.0 that ads a new scope (id_token) which alters the existing flows by inserting the id_token generaetion (where the flow allows it). For a request_type=code it’s enough to add the new scope id_token and the flow will
be altered to include this token. There is a new Hybrid Flow added with OpenID, this one is called the Hybrid Flow and what this one does is to combine the Implicit flow with the Authorization Flow.
- AuthorizationCode Flow:
- Returns an authorization code that can be exchanged for an identity token
- Requires authentication using a client_id and client_secret to get the token from the backend
- Implicit Flow:
- Tokens without explicit client authentication
- Refresh tokens are not allowed
- Hybrid Flow:
- Combines aspects of the previous 2
- This flow allows the client to make immediate use of an id_token and auth_code by making one round trip to the authorization server
These flows can be split in 2 categories depending on the steps they require:
- 2-Legged flows (client_credentials, resourceownercredentials, implicit)
- 3-Legged flos (authorization_code – because it requires the extra redirection step)
Authorization Flow Dance
To much theory without a basic sketch helps no one. Each flow has it’s own diagram but the authorization_code one is more complex. Below is a basic diagram that shows the steps taken from the request untill the authorization.
response_type vs grant_type
A response_type targets the authorization end point. It can contain the following items : code, id_token, token or a combination of those. A response type is provided by the client app and this tells the authorization server what it expects from it (a code, a token, etc). Based on this request, the server will try to start a certain flow (considering that the client is allowed)
A grant_type targets the end point. And it’s used when the client wants to exchange an authorization code for an access_token or when it wants to use the refresh token to get a new access_code. get a new. If the client is a granted access to this information (by the GrantTypes defined) then the server will issue the information
A GrantType on the server side will allow the client app to issue certain kinds of information. This defines what flow can the client handle
Where the GrantTypes.Code() actually maps to the following grant: