How I can enable multi resource support in iOS using ADAL.Searched in so many sites, but finding it difficult to understand the flow with multiple resources, with Refresh Token and Access Token.Can anyone explain this flow briefly please?
According to library, ADTokenCacheStoreItem will have accessToken will be nil, in case the item stores multi-resource refresh token.But whenever I will call acquireTokenWithResource:clientId:redirectUri: I am getting both access token and refresh token.How I can tell the library that mine is multi source request.Is there any settings I need to do?
/*! The access token received. Should be nil, in case the item stores multi-resource refresh token. /
#property NSString accessToken;
And also , do I need to call the acquireTokenWithResource:clientId:redirectUri every time before calling each API with or without different end points.Or is it my responsibility to cache/store the access token and expiry date for each resource?
Also how I can handle silent login in multi resource case?
With ADAL, you simply need to call some form of acquireToken* each time your application needs an access token, presumable to make an API call. ADAL should take care of token caching, refreshing, etc for you. You shouldn't ever have to manually use refresh tokens.
Refresh tokens from Azure AD are inherently "multi-resource". That is, you can ask for an access token to resource 1, receive that access token + refresh token pair, and then use the refresh token to get an access token to resource 2. This allows you to get tokens for different resources "silently", meaning the user only has to sign-in once.
Related
I build an application that must use delegated AAD permissions to interact with the Graph API. App permissions are no option due to secruity restrictions.
This application is a background service which has some minimal UI for configuration of the application. The idea is to have users log into the UI once (via AAD), granting the required permissions. After that users will mostly never need to use this UI as there is nothing vital to configure.
This creates a situation where the user will only once present a usable access token. After that initial onboarding, the application will have to use a refresh token once in a while to keep being able to use the Graph API.
Is my assumption correct that in order for this to work, I must persist refresh tokens of each user? Intuitively this seems like both a security risk (if not implemented properly) and also a kind of complex system which would not only store tokens but also have additional background refreshing tokens and potentially informing users about eventual expired tokens (in case of failing token refreshs).
Yes, the refresh token you receive back is unique for each user, so you really need to keep the refresh and access token separate between each user and store them in a secure way.
Please also note that in some systems you get a new refresh token each time you use it.
Either you use the refresh token with a timer and refresh them each XX minutes. Or you do the refresh when the user receives a 401 Not Authenticated response from the API.
Is it possible to "reduce" scopes in OAuth? Scope reduction should be initiated by the client.
Meaning: Request a new Access Token using the Refresh Token, but the new token has less scopes than the "original" one?
Use case: I'm developing a client application that authenticates users via OAuth with another party (A). Now I want to give yet another party (B) access to some scopes, but less than I have.
Unfortunately there's no standard way to do what you want, but even if there were, you can't often get a new access token without destroying the old access token.
Access tokens are per-client. Once it expires, you can use a refresh token to get a new access token, but many systems are implemented in a way that a refresh token can only be used once and that the original access token immediately (or quickly) expires.
If you control the server, it's definitely possible to implement this as a new, custom grant type, effectively an extension of OAuth2.
According to https://www.rfc-editor.org/rfc/rfc6749#section-6 you should be able to add a scope field on a refresh request, as long as your requested scopes are a subset of the originals and your refresh token is still valid.
Note that the reduced scopes only apply to the access token, so if you leak a long lived refresh token to a third party they can get all the scopes it had.
Since using the refresh token gives you a new pair of tokens, what is the advantage of doing a refresh versus just obtaining a new Auth token? For example:
65 minutes after obtaining a token, I have to refresh it (and obtain a new token), or
just obtain a new one
Why not just get a new access token each time?
If I am doing everything within my own server / within my own code, is there any benefit to refreshing. Or is it as good to obtain a new token every hour?
I get the gist of the refresh in some circumstances, but when it's all in my control, is refresh token necessary?
Advantage relies with easiness of obtain access token.
Think about Authorization code flow. If you do not get a refresh token, client application have to trigger a new authorization code flow to retrieve a new access token. This include end user interactions for user grants (end user login in simple terms). For some applications, such re-login is not a desired feature. For them having a refresh token is a very desirable feature.
So when you design your application, if you don't want your end users to provide their credentials every time client application want an access token, then you should use refresh token. But if this is not the case and you have other ways to complete access token obtaining process then it's rather a design decision.
Per Google's docs it would seem refresh tokens are only necessary for offline applications (applications that may run into an expired access token when the user isn't around).
Access tokens periodically expire. You can refresh an access token
without prompting the user for permission (including when the user is
not present) if you requested offline access to the scopes associated
with the token.
...
Requesting offline access is a requirement for any application that
needs to access a Google API when the user is not present. For
example, an app that performs backup services or executes actions at
predetermined times needs to be able to refresh its access token when
the user is not present. The default style of access is called online.
However, a description of refresh tokens in general and this question in particular both seem to imply that refresh tokens are needed anytime you want to request a new access token.
I think I would agree with Google's explanation and not use refresh tokens. My experience with OIDC providers has been that refresh works as follows:
User requests protected resource from client server
Client server determines access token has expired.
Client server redirects user to OP auth endpoint
OP authenticates user without interaction due to cookies stored on user's browser with OP's domain.
Client server finishes the request.
The user might see a few redirects but other than that the re-authentication went by without any interaction from them. Given this, is it necessary to bother with refresh tokens if the user will always be present at the application?
My biggest concern with using refresh tokens for online apps is that it takes away transparency from the user.
Refresh tokens facilitate long term access and should be stored safely. But they also don't provide a natural way to "sign out", and (most importantly) it becomes completely opaque how, when and from where your data is accessed, as the often used scope name offline_access suggests.
OIDC offers a front channel mechanism prompt=none that largely leads to the same effect (i.e. new tokens), and without needing intermediate redirects if the re-authentication is performed inside an iframe.
Hence in my opinion you and Google are right and the answer must be: No, don't use refresh tokens if the user is present.
No, it is not necessary to bother with refresh tokens if the user will always be present at the application. The reasoning is largely the OP describes.
But there are reasons why one may still want a refresh token:
as the OP mentions the user might see a few redirects and both the UI expert and the branding guy on your team will hate this
when an access token expires in the middle of an HTML Form POST action, the redirect may have lost the context/POST-data on return; you may want to minimize this or you'll have to take appropriate (complex) POST-data-save actions
if your access token expiry is really short, the redirects create a lot of overhead and nuisance; you may not be able to control access token expiry when dealing a Providers in a different domain and when dealing with multiple Providers it will vary across them
when refreshing the access token with a redirect your application now depends on the Provider keeping an SSO session; not all Providers may do this and if they do they may do it in different ways: the SSO session duration may vary between them and the authentication method may vary; as an example: a Provider that doesn't keep an SSO session but does use 2-factor authentication will have large impact on the user experience
Imagine a scenario where you want to use the access token to update user information in almost real-time from the user info endpoint but the access token expiry is relatively short. Either you'll have to perform a lot of redirects with the nuisance as described, or you can use a refresh token.
Refresh token is essentialy a credential reference, that your client can exchange for access token, when there is no active user session.
For example if you want to periodicaly sync issues from Github with your inhouse system.
It is often misused like some kind of session. It is essential to diffirentiate those things. And scope name offline_access is there for a reason.
So in simple cases - you just rely on OP session and get new token with authorize/token endpoints combo. You should not be prompted to provide credentials as long as session is alive and consent is given for that particular app.
If you need to do some backgound stuff - ask for refresh token also.
As for question: no.
EDIT(More in-depth explanation):
if we are talking about web there are two main cases:
Client that can securely store secrets like usual web app with server page rendering and clients, that cant store secrets, like SPA apps. From that perspective there are two main flows (omitting hybrid to not over-complicate): Authorization Code Flow and Implicit Flow respectively.
Authorization Code Flow
On first request your app checks it own session(client session) and if there is none - redirects to external OP(OpenID Connect provider) authorize url. OP authenticates user according to requirements expressed in request, gathers consent and other stuff and returns authorization code. Then client asks token endpoint with it and receives access_token/id_token pair with optional refresh token if user granted offline access consent. This is important, because user can deny it for your app. After this client can request userInfo endpoint to get all user claims that were granted during consent. Those claims represent user identity and do not contain stuff like authentication method, acr etc. Those claims present in id_token alongside with expiration for example. After that client starts it own session and have option to set its lifetime equal to id_token lifetime or use it own to provide smooth UX for example. At this point you can discard access_token and id_token at all if you don't need access to other APIs(like all scopes in access_token are specific to OP and subject). If you need access to some API you can store access_token and use it for access. It becomes invalid - redirect to OP for new one. Expiration can be more lax here, because of more secure environment on server. So even 1hr is an option. No refresh tokens used at all.
Implicit Flow
In this case your lets say Angular app redirects to OP, gets its id_token and optional access_token from authorize endpoint directly and uses it to access some APIs. On every request expiration is checked an if needed, client sends request to OP in hidden iFrame, so there won't be any visible redirects as long as OP session is alive. There are some great libs for that like openid-client.js. No refresh is allowed here at all.
It is important to differentiate client session from OP session, token lifetime and session lifetime.
To address some specific needs there is Hybrid Flow. It can be used to get authorization code and id_token for your session in one request. No chit chat over network.
So when you think about refresh token just check your needs and map them to a spec :) And if you need it anyway - store it as secure as you can.
Refresh tokens are useful for applications that keep access tokens in a server session. For example if a web application doesn't call a protected service using JavaScript XHR, but calls its backend and the backend calls the service. In this scenario, it's easier to get a new access token whenever it's needed than asking a user for a new one.
In JavaScript applications running in browsers, refresh tokens cannot be used, because you need a client secret to get an access token from the /token endpoint and you cannot keep the secret safe in such applications.
The process for getting new access tokens you described can be improved - an application may ask for a new access token just before the current one expires, so the user doesn't get redirected to the OAuth2 server, but the application calls the /auth endpoint with prompt=none parameter in an iframe.
Why not use just one for everything? Refresh token doesn't change by default, so why bother to get an access token every hour? API: https://developers.google.com/youtube/2.0/developers_guide_protocol_oauth2#OAuth2_Server_Side_Web_Applications_Flow
They choose that the given access does not last forever: So you need to get a new access token once it has expired.
The purpose of the refresh token is that you have to ask the user for permission only one time.
Here's a good discussion on the topic.
When you get a refresh token, you also need the client ID and secret. With an access token, you can make API calls using just that. A lot of this comes form learnings from OAuth 1.x, which had a much more complex signing protocol - it just caused lots of bugs and problems with client/server protocol mismatch. Using only an access token made API calls, the most important part of OAuth, much easier to implement and maintain.