[Openid-specs-ab] Online Access Refresh Tokens
kmcguinness at okta.com
Fri Jan 3 22:59:36 UTC 2020
Thanks Torsten and David for the feedback, I was out for the holiday and slowly catching up on email
I agree with current OAuth 2.0 defined behaviors in the context of traditional OAuth 2.0 Authorization Servers that are intended to delegate access to a protected resources. Refresh tokens should not have a predefined relationship to a user’s session on the AS and the AS can always enforce any policy it chooses around issuing/revoking refresh tokens and their lifetimes. I also agree with David’s comments about the issues around offline_access scope as defined in OIDC.
Let me rewind a bit to share what prompted the session at IIW.
The discussion was focused on the intersection of OIDC, developers using external Identity Servers/Services, deprecation of implicit flow, and the OAuth 2.0 for Browsers BCP. The behavior developers observe today with implicit flow across AS/OP implementations is that they can only obtain new access tokens for previously consented scopes if a session exists in the browser. They can silently renew access tokens with prompt=none requests in background iframes/etc. This can be implemented in a SDK creating a very simple developer pattern, use existing access token, on expiration silently renew and if oauth error login_required is returned then redirect back to the OP and start over.
The AS/OP can always issue non-expiring or long-term access token that is cached in localStorage but in our experience most of the SPAs using an external Identity Service want to also outsource session management and typically configure the AS/OP to use more reasonable lifetimes in minutes. This has the side affect of users perceiving a logout at the Identity Server (AS/OP) also kills the SPA sessions. Yes there is SLO & session management extensions defined in OIDF but front channel redirect patterns introduce more surface area and developers seem to like this whole serverless trend that constrain backchannel approaches. Additionally browsers are making it extremely hostile to to do anything cross-origin with cookies (https://textslashplain.com/2019/07/05/challenges-with-federated-identity-in-modern-browsers/) limiting the usefulness of extensions like Session Management (https://openid.net/specs/openid-connect-session-1_0.html).
Developers using the implicit flow that assumed they could only obtain access tokens if a session is valid will need to resolve this requirement gap to keep existing assumptions. Now that we are standardizing on authorization code flow for all app types (browser, web, and native) and have a context handle for a session that can live outside of cookies (refresh token) , we can dramatically simplify session & token management for SPAs with Identity Servers that would be interoperable across AS/OP implementations. I fear more interop issues resulting from OAuth 2.0 for Browsers BCP if an alternative pattern for this category of app is not defined. The “online_access” scope proposal was trying to reuse prior art for this use case to help clarify ambiguity across implementations. I’m open to other approaches.
I guess the question is do other folks see this need or is it just something we need to address in our implementation using something proprietary to our implementation? The feedback I got from IIW was having a defined pattern would help interoperability.
On Dec 24, 2019, at 5:22 AM, Torsten Lodderstedt <torsten at lodderstedt.net<mailto:torsten at lodderstedt.net>> wrote:
thanks for bringing this topic up. It caused me to think about token lifecycle again. Here are my thoughts:
First of all, I think the decision to let the AS decide when to issue refresh tokens makes a lot of sense. Whether refresh tokens are needed typically depends on the lifetime and the scope of the access tokens. If the AS issues multi/any audience long living access tokens, there is no value in having refresh tokens. If the AS, in contrast, issues short living access tokens or access tokens only representing a portion of the underlying grant, there is a need for refresh tokens as representation of this grant. So clients must be prepared to handle refresh tokens, but the AS should decide based on its needs and policy.
I also think there shouldn’t be a relationship between the tokens issued by an AS and a session with the AS. OAuth is about delegating access to an application, that's what access tokens are made for. Whether the OAuth AS utilises a login session in the authorisation for or not does not matter in this context. There are even ASs which do not use sessions at all!
OpenID Connect plays a special role since the client depends on the AS/OP to provide the user’s identity. In 1st party scenarios, this typically also means to synchronise the sessions including single logout. But even in this case I’m not sure there is a need to bind the lifecycle of a refresh token to the session lifetime at the AS. Why? Because the access tokens obtained from this refresh tokens are intended to be used at the UserInfo endpoint, which is an ordinary RESTful API. The data obtained from this endpoint are still valid, even if the user’s session with the OP is gone.
I think session synchronization between OP and RP should happen in the front channel based on either OpenID authentication requests with prompt=none or the OpenID session management extension.
Having said that I would like to understand why you think access tokens issued to SPAs should be invalidated on logout and session expiration. The use case you describe to me sounds like session synchronisation.
Clearly, the AS can at any time decide to invalidate a refresh token and any client must be able to cope with this. This also means, any AS could offer a “revoke refresh token on logout” feature, if you think that’s required for a certain deployment or client. I agree with DW that this can be made a policy rather than a request level parameter.
On 22. Dec 2019, at 09:03, David Waite via Openid-specs-ab <openid-specs-ab at lists.openid.net<mailto:openid-specs-ab at lists.openid.net>> wrote:
A number of comments.
There are issues with the way that offline access is defined today. I think a number of these also translate to an online access scope, plus a few additional issues.
First, offline_access is unfortunately defined tied to refresh tokens, when no _actual_ protocol tie is present (nor is the use of refresh tokens in offline access patterns a MUST).
I can have refresh tokens in an authorization tied to the OP concept of a user session. Likewise, I can issue a non-time-limited access token for a confidential client to use, without a refresh token and with expiry only being via some external process. The definition of offline_access has caused unfortunate confusion by implementors, who believe refresh tokens are somehow incompatible with tying authentication to a user session, and that refresh tokens are required for independent access.
However, I don’t believe this requires a new scope name. Rather, this could be solved with clarifying how offline_access may be applied outside the context of OpenID Connect.
Secondly (and IMHO), use of offline_access itself is an anti-pattern for some deployments. A single client’s behavior within the system will almost never dynamic enough to need offline behavior for a user in one case, and session-bound behavior in another. Generically expecting clients to indicate whether they need offline behavior is a sign that clients in the environment are not properly classified or audited for their actual needs. The only AS/OP environments where this really is acceptable is when you expect users to be the sole line of defense against inappropriate requests by clients for permissions - but even large social providers like Facebook and GitHub have started to decide this is unacceptable.
Finally, (and also IMHO) while I understand the modeling of online_access to be explicit that underspecified clients should have any refresh tokens bound to the session, I don’t believe a scope is appropriate way to model a client opting into _limitations_ on the authorization. Other scopes when requested increase the capabilities of the token or the information the client has access to - access to authentication information and user claims with most of the OIDC-defined scopes, access to additional API capabilities with typical OAuth scopes. In this case, clients would be opting into having to send the user through an authorization UX more often - which is not something I see a client developer normally seeking out how to do.
As part of the overall authentication and authorization policy this is all the responsibility of the OP to dictate. It is not appropriate for the client to opt into behavior based on its own self-assertion around security and design.
I further assert that in the rare cases where it is appropriate for a client to indicate off-line or on-line patterns for access, these are the only two apparent policy options which could be broadly standardized. In that case, the absence of an offline_access scope is the same as some online_access scope.
On Dec 21, 2019, at 12:24 PM, Karl McGuinness via Openid-specs-ab <openid-specs-ab at lists.openid.net<mailto:openid-specs-ab at lists.openid.net>> wrote:
Online Access Refresh Tokens
Online Access Refresh Tokens. GitHub Gist: instantly share code, notes, and snippets.
Hello OpenID Connect WG,
I hosted a session at IIW last fall discussing the need to introduce support for online_access refresh tokens. I promised to write up the takeaways and send to the OpenID Connect mailing list. I finally found the time before the year closes to complete that promise!
The OAuth 2.0 Authorization Framework defines the authorization_code grant type and refresh token. It doesn't establish any rules for issuing refresh tokens and explicitly states in Section 1.5 that "Issuing a refresh token is optional at the discretion of the authorization server". One of the explicit goals for Rfc6749 was to enable offline access to protected resources when the end-user is not present. It does not define any request semantics for how a client can explicitly request a refresh token or whether that refresh token's lifecycle should be bound to the user's session that granted the refresh token. Authorization Servers are free to define these behaviors on a per-implementation or policy basis.
OpenID Connect being the identity layer ontop of OAuth 2.0 needed to define some new authorization server behaviors to enable end-user consent for when a client can access their identity info (UserInfo). This resulted in a new scope offline_access being defined to allow a client to access their identity info when they are not present.
OPTIONAL. This scope value requests that an OAuth 2.0 Refresh Token be issued that can be used to obtain an Access Token that grants access to the End-User's UserInfo Endpoint even when the End-User is not present (not logged in).
OpenID Connect 1.0 does not define how the offline_access scope should constrain access to other protected resources, nor does it define the behavior of the refresh token if this scope is not requested. Authorization Servers are free to define behaviors for other protected resources and/or non-OIDC defined scopes when offline_access is requested.
The use of Refresh Tokens is not exclusive to the offline_access use case. The Authorization Server MAY grant Refresh Tokens in other contexts that are beyond the scope of this specification.
There are many large scale OAuth 2.0 deployments the have chosen to only issue refresh tokens for delegated access to their protected non-identity resources only if offline_access scope is requested. This approach often simplified Authorization Server complexity and developer documentation by linking the offline_access OIDC constrain to all protected resources.
OpenID Connect 1.0 also does not define any new behaviors for when an issued refresh tokens should be linked to the authentication session that issued the authorization code/refresh token. Logging out of the OP is an implementation-specific behavior with respect to any issued refresh tokens that were not requested with offline_access scope.
This lack of clarity hasn't historically been a significant issue as refresh tokens were restricted from being issued via the implicitgrant in Section 4.2. Refresh tokens were often only used for web or native clients where offline_access was the desired behavior (raison d'etre of OAuth 2.0)
As developers shift to more browser-based applications (e.g Single Page Apps) and leverage cloud identity services, the need to resolve this undefined behavior has reached a tipping point. The OAuth 2.0 for Browser-Based Apps BCP and OAuth 2.0 Security Best Current Practice BCP deprecate the implicit grant and require all browser-based applications to use the authorization_code grant with PKCE. This change requires defining new behaviors for refresh tokens in the browser where it previously never was used. Section 8of the BCP defines security mitigations to prevent refresh tokens from being leaked but does not define what should happen if the user logs out of the authorization server.
When browser-based apps used the implicit grant they often used patterns like making authentication requests with prompt=none to silently request new access tokens when previously issued access tokens were expired. This pattern relied on the client and the end-user being in the same browser context and having a session with the OP. Logout at OP would prevent these clients from obtaining new access tokens. This not only had security benefits but also user experience benefits especially when switching accounts at the OP.
It is desirable to have an explicit pattern for a client to opt-in to a refresh token that is tightly coupled to the user's session at the Authorization Server. An explicit pattern enables the client to express it's intent on whether it wants to operate in a connected or disconnected mode. The Authorization Server can choose to honor this intent or not based on policy.
The recommendation was to introduce a new online_access scope that when requested, binds the issued refresh token to user's session on the Authorization Server. If the user's session is closed or revoked either directly by end-user or indirectly by the Authorization Server such as an inactivity timeout policy the refresh token and children access tokens issued with the refresh token MUST be revoked by the Authorization Server.
Revoking the issued refresh token directly via Token Revocation Endpoint or indirectly via the Authorization Server should only revoke the refresh token and children access tokens and not the user's session.
If the need arises to revoke the user's session at the Authorization Server via the backchannel with a Refresh Token, then a new extension to Logout Specifications should be defined.
The recommendation was to define the new online_access in OIDF as this is consistent with offline_access and relates to authentication concerns. Once defined in OIDF, we can reference in OAuth 2.0 for Browser-Based Apps BCP. We should maybe consider introducing a new client application_type (e.g. browser) that requires online_access scope.
The healthcare domain has defined a similar use of online_access with the HL7 FHIR specifications.
Openid-specs-ab mailing list
Openid-specs-ab at lists.openid.net
Openid-specs-ab mailing list
Openid-specs-ab at lists.openid.net<mailto:Openid-specs-ab at lists.openid.net>
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Openid-specs-ab