Access Tokens and Refresh Tokens
So far we’ve talked mostly in terms of access tokens because access tokens are the only thing a resource server will accept to authorize a client. The problem now becomes, how long should the token be valid for? On the one hand it should be short enough so that authorization can be revoked in a timely manner; on the other hand you don’t want to make the end-user continually entering their credentials. The OAuth answer to this is the refresh token which can be used to get a new authorization token when the previous authorization token expires. In case a user’s access is revoked, the refresh token will not be honored but under normal operation the client application can get a new access token without asking the end-user to continually authenticate. As you can check in the example code, the client credential grant doesn’t return a refresh token but the authorization grant will (optionally) return a refresh token.
Claims are sent in the access token which Azure encodes as a JSON Web Token (JWT). JWT is comparable to a SAML token but sacrifices some security options and expressivity for simplicity and size; it’s designed to fit into HTTP headers and URI query arguments.
The refresh token is not a JWT token. I suspect this is because the refresh token is generated by the authorization server and is designed to only be consumed by the authorization server (but that’s just me speculating).
Azure will send claims embedded in the access token but different types of grants provide different claims, as you can see below. Using the ADAL tools, these claims will be added to the security principal on the resource server, the same as WIF would do in a claims-based authentication example.
Authorization Code Grant Claims:
family_name: De Fermat
Client Credential Code Grant Claims:
ADAL is clever enough to cache your access and refresh tokens so that multiple calls to AquireToken will not necessarily incur the overhead of calling the authentication server. In the example code I store the tokens in properties but you would never do that in production code; ADAL handles stores tokens transparently.
I have been omitting an OAuth implementation detail which ADAL abstracts this from the developer but as you may already know, the authorization server actually exposes two endpoints: the authorization endpoint and a token endpoint. The former deals with the resource owner to gain an authorization grant; the latter issues tokens. The details themselves aren’t too important, except that it is good to know they exist but I find the passage from the specification which describes the authorization server interesting.
The authorization endpoint is used to interact with the resource owner and obtain an authorization grant. The authorization server MUST first verify the identity of the resource owner. The way in which the authorization server authenticates the resource owner (e.g., username and password login, session cookies) is beyond the scope of this specification.
This is a pretty good clue that OAuth 2 is an authorization protocol and should not be used for authentication, despite the user claims sometimes included in the access token e.g. upn, unique_name, first_name, last_name etc.