| < draft-ietf-oauth-native-apps-03.txt | draft-ietf-oauth-native-apps-04.txt > | |||
|---|---|---|---|---|
| OAuth Working Group W. Denniss | OAuth Working Group W. Denniss | |||
| Internet-Draft Google | Internet-Draft Google | |||
| Intended status: Best Current Practice J. Bradley | Intended status: Best Current Practice J. Bradley | |||
| Expires: January 21, 2017 Ping Identity | Expires: April 15, 2017 Ping Identity | |||
| July 20, 2016 | October 12, 2016 | |||
| OAuth 2.0 for Native Apps | OAuth 2.0 for Native Apps | |||
| draft-ietf-oauth-native-apps-03 | draft-ietf-oauth-native-apps-04 | |||
| Abstract | Abstract | |||
| OAuth 2.0 authorization requests from native apps should only be made | OAuth 2.0 authorization requests from native apps should only be made | |||
| through external user-agents, primarily the system browser. This | through external user-agents, primarily the user's browser. This | |||
| specification details the security and usability reasons why this is | specification details the security and usability reasons why this is | |||
| the case, and how native apps and authorization servers can implement | the case, and how native apps and authorization servers can implement | |||
| this best practice. | this best practice. | |||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at http://datatracker.ietf.org/drafts/current/. | Drafts is at http://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on January 21, 2017. | This Internet-Draft will expire on April 15, 2017. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2016 IETF Trust and the persons identified as the | Copyright (c) 2016 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (http://trustee.ietf.org/license-info) in effect on the date of | (http://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| skipping to change at page 2, line 13 ¶ | skipping to change at page 2, line 13 ¶ | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | |||
| 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 3 | 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 3 | |||
| 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | 4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 4.1. Authorization Flow for Native Apps Using App-Claimed URI | 4.1. Authorization Flow for Native Apps Using the Browser . . 5 | |||
| Schemes . . . . . . . . . . . . . . . . . . . . . . . . . 4 | ||||
| 5. Using Inter-app URI Communication for OAuth . . . . . . . . . 6 | 5. Using Inter-app URI Communication for OAuth . . . . . . . . . 6 | |||
| 6. Initiating the Authorization Request . . . . . . . . . . . . 6 | 6. Initiating the Authorization Request from a Native App . . . 6 | |||
| 7. Receiving the Authorization Response . . . . . . . . . . . . 7 | 7. Receiving the Authorization Response in a Native App . . . . 7 | |||
| 7.1. App-declared Custom URI Scheme Redirection . . . . . . . 7 | 7.1. App-declared Custom URI Scheme Redirection . . . . . . . 7 | |||
| 7.2. App-claimed HTTPS URI Redirection . . . . . . . . . . . . 9 | 7.2. App-claimed HTTPS URI Redirection . . . . . . . . . . . . 8 | |||
| 7.3. Loopback URI Redirection . . . . . . . . . . . . . . . . 9 | 7.3. Loopback URI Redirection . . . . . . . . . . . . . . . . 8 | |||
| 8. Security Considerations . . . . . . . . . . . . . . . . . . . 10 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 9 | |||
| 8.1. Embedded User-Agents . . . . . . . . . . . . . . . . . . 10 | 8.1. Embedded User-Agents . . . . . . . . . . . . . . . . . . 9 | |||
| 8.2. Protecting the Authorization Code . . . . . . . . . . . . 11 | 8.2. Protecting the Authorization Code . . . . . . . . . . . . 10 | |||
| 8.3. Phishability of In-App Browser Tabs . . . . . . . . . . . 12 | 8.3. Loopback Redirect Considerations . . . . . . . . . . . . 11 | |||
| 8.4. Limitations of Non-verifiable Clients . . . . . . . . . . 12 | 8.4. Registration of App Redirection URIs . . . . . . . . . . 11 | |||
| 9. Other External User Agents . . . . . . . . . . . . . . . . . 12 | 8.5. OAuth Implicit Flow . . . . . . . . . . . . . . . . . . . 11 | |||
| 10. Client Authentication . . . . . . . . . . . . . . . . . . . . 13 | 8.6. Phishability of In-App Browser Tabs . . . . . . . . . . . 12 | |||
| 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 13 | 8.7. Limitations of Non-verifiable Clients . . . . . . . . . . 12 | |||
| 11.1. Normative References . . . . . . . . . . . . . . . . . . 13 | 8.8. Non-Browser External User Agents . . . . . . . . . . . . 12 | |||
| 11.2. Informative References . . . . . . . . . . . . . . . . . 13 | 8.9. Client Authentication . . . . . . . . . . . . . . . . . . 13 | |||
| Appendix A. Operating System Specific Implementation Details . . 15 | 8.10. Cross-App Request Forgery Protections . . . . . . . . . . 13 | |||
| A.1. iOS Implementation Details . . . . . . . . . . . . . . . 15 | 8.11. Authorization Server Mix-Up Mitigation . . . . . . . . . 13 | |||
| A.2. Android Implementation Details . . . . . . . . . . . . . 15 | 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 | |||
| A.3. Windows Implementation Details . . . . . . . . . . . . . 16 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
| A.4. macOS Implementation Details . . . . . . . . . . . . . . 16 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 14 | |||
| Appendix B. Acknowledgements . . . . . . . . . . . . . . . . . . 17 | 10.2. Informative References . . . . . . . . . . . . . . . . . 14 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 17 | Appendix A. Server Support Checklist . . . . . . . . . . . . . . 15 | |||
| Appendix B. Operating System Specific Implementation Details . . 15 | ||||
| B.1. iOS Implementation Details . . . . . . . . . . . . . . . 16 | ||||
| B.2. Android Implementation Details . . . . . . . . . . . . . 16 | ||||
| B.3. Windows Implementation Details . . . . . . . . . . . . . 16 | ||||
| B.4. macOS Implementation Details . . . . . . . . . . . . . . 17 | ||||
| B.5. Linux Implementation Details . . . . . . . . . . . . . . 17 | ||||
| Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 17 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 18 | ||||
| 1. Introduction | 1. Introduction | |||
| The OAuth 2.0 [RFC6749] authorization framework, documents two | The OAuth 2.0 [RFC6749] authorization framework documents two | |||
| approaches in Section 9 for native apps to interact with the | approaches in Section 9 for native apps to interact with the | |||
| authorization endpoint: via an embedded user-agent, or an external | authorization endpoint: an embedded user-agent, or an external user- | |||
| user-agent. | agent. | |||
| This document recommends external user-agents like in-app browser | This best current practice recommends that only external user-agents | |||
| tabs as the only secure and usable choice for OAuth. It documents | like the browser are used for OAuth by native apps. It documents how | |||
| how native apps can implement authorization flows with such agents, | native apps can implement authorization flows using the browser as | |||
| and the additional requirements of authorization servers needed to | the preferred external user-agent, and the requirements for | |||
| support such usage. | authorization servers to support such usage. | |||
| This practice is also known as the AppAuth pattern, in reference to | ||||
| open source libraries that implement it. | ||||
| 2. Notational Conventions | 2. Notational Conventions | |||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
| "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
| "OPTIONAL" in this document are to be interpreted as described in Key | "OPTIONAL" in this document are to be interpreted as described in Key | |||
| words for use in RFCs to Indicate Requirement Levels [RFC2119]. If | words for use in RFCs to Indicate Requirement Levels [RFC2119]. If | |||
| these words are used without being spelled in uppercase then they are | these words are used without being spelled in uppercase then they are | |||
| to be interpreted with their normal natural language meanings. | to be interpreted with their normal natural language meanings. | |||
| 3. Terminology | 3. Terminology | |||
| In addition to the terms defined in referenced specifications, this | In addition to the terms defined in referenced specifications, this | |||
| document uses the following terms: | document uses the following terms: | |||
| "app" A native application, such as one on a mobile device or | "native app" An application that is installed by the user to their | |||
| desktop operating system. | device, as distinct from a web app that runs in the browser | |||
| context only. Apps implemented using web-based technology but | ||||
| distributed as a native app, so-called hybrid apps, are considered | ||||
| equivalent to native apps for the purpose of this specification. | ||||
| "OAuth" In this document, OAuth refers to OAuth 2.0 [RFC6749]. | ||||
| "app" Shorthand for "native app". | ||||
| "app store" An ecommerce store where users can download and purchase | "app store" An ecommerce store where users can download and purchase | |||
| apps. Typically with quality-control measures to protect users | apps. | |||
| from malicious developers. | ||||
| "authz" Abbreviation of "authorization". | "authz" Abbreviation of "authorization". | |||
| "system browser" The operating system's default browser, typically | "browser" The operating system's default browser, pre-installed as | |||
| pre-installed as part of the operating system, or installed and | part of the operating system, or installed and set as default by | |||
| set as default by the user. | the user. | |||
| "browser tab" An open page of the system browser. Browser typically | "browser tab" An open page of the browser. Browser typically have | |||
| have multiple "tabs" representing various open pages. | multiple "tabs" representing various open pages. | |||
| "in-app browser tab" A full page browser with limited navigation | "in-app browser tab" A full page browser with limited navigation | |||
| capabilities that is displayed inside a host app, but retains the | capabilities that is displayed inside a host app, but retains the | |||
| full security properties and authentication state of the system | full security properties and authentication state of the browser. | |||
| browser. Has different platform-specific product names, such as | ||||
| SFSafariViewController on iOS 9, and Chrome Custom Tab on Android. | ||||
| "Claimed HTTPS URL" Some platforms allow apps to claim a domain name | Has different platform-specific product names, such as | |||
| by hosting a file that proves the link between site and app. | SFSafariViewController on iOS, and Chrome Custom Tab on Android. | |||
| Typically this means that URLs opened by the system will be opened | ||||
| in the app instead of the browser. | ||||
| "web-view" A web browser UI component that can be embedded in apps | "inter-app communication" Communication between two apps on a | |||
| to render web pages, used to create embedded user-agents. | device. | |||
| "reverse domain name notation" A naming convention based on the | "claimed HTTPS URL" Some platforms allow apps to claim a HTTPS URL | |||
| domain name system, but where where the domain components are | after proving ownership of the domain name. URLs claimed in such | |||
| reversed, for example "app.example.com" becomes "com.example.app". | a way are then opened in the app instead of the browser. | |||
| "custom URI scheme" A URI scheme (as defined by [RFC3986]) that the | "custom URI scheme" A URI scheme (as defined by [RFC3986]) that the | |||
| app creates and registers with the OS (and is not a standard URI | app creates and registers with the OS (and is not a standard URI | |||
| scheme like "https:" or "tel:"). Requests to such a scheme | scheme like "https:" or "tel:"). Requests to such a scheme | |||
| results in the app which registered it being launched by the OS. | results in the app which registered it being launched by the OS. | |||
| For example, "myapp:", "com.example.myapp:" are both custom URI | ||||
| schemes. | ||||
| "inter-app communication" Communication between two apps on a | "web-view" A web browser UI component that can be embedded in apps | |||
| device. | to render web pages, used to create embedded user-agents. | |||
| "OAuth" In this document, OAuth refers to OAuth 2.0 [RFC6749]. | "reverse domain name notation" A naming convention based on the | |||
| domain name system, but where where the domain components are | ||||
| reversed, for example "app.example.com" becomes "com.example.app". | ||||
| 4. Overview | 4. Overview | |||
| At the time of writing, many native apps are still using web-views, a | The best current practice for authorizing users in native apps is to | |||
| type of embedded user-agent, for OAuth. That approach has multiple | perform the OAuth authorization request in a browser (an external | |||
| drawbacks, including the client app being able to eavesdrop user | user-agent), rather than web-view (an embedded user-agent). | |||
| credentials, and is a suboptimal user experience as the | ||||
| authentication session can't be shared, and users need to sign-in to | ||||
| each app separately. | ||||
| OAuth flows between a native app and the system browser (or another | Previously it was common for native apps to use web-views for OAuth | |||
| external user-agent) are more secure, and take advantage of the | authorization requests. That approach has many drawbacks, typically | |||
| shared authentication state to enable single sign-on. | including the host app being able to copy user credentials and | |||
| cookies, and the user needing to authenticate from scratch in each | ||||
| app. See Section 8.1 for a deeper analysis of using embedded user- | ||||
| agents for OAuth. | ||||
| Inter-process communication, such as OAuth flows between a native app | Native app authorization requests that use the browser are more | |||
| and the system browser can be achieved through URI-based | secure and can take advantage of the user's authentication state. | |||
| communication. As this is exactly how OAuth works for web-based | Being able to use the existing authentication session in the browser | |||
| OAuth flows between RP and IDP websites, OAuth can be used for native | enables single sign-on, as users don't need to authenticate to the | |||
| app auth with very little modification. | authorization server each time they use a new app (unless required by | |||
| authorization server policy). | ||||
| Supporting authorization flows between a native app and the browser | ||||
| is possible without changing the OAuth protocol itself, as the | ||||
| authorization request and response are already defined in terms of | ||||
| URIs, which emcompasses URIs that can be used for inter-process | ||||
| communication. Some OAuth server implementations that assume all | ||||
| clients are confidential web-clients will need to add an | ||||
| understanding of native app OAuth clients and the types of redirect | ||||
| URIs they use to support this best practice. | ||||
| 4.1. Authorization Flow for Native Apps Using the Browser | ||||
| 4.1. Authorization Flow for Native Apps Using App-Claimed URI Schemes | ||||
| +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | |||
| | User Device | | | User Device | | |||
| | | | | | | |||
| | +---------------------------+ | +-----------+ | | +---------------------------+ | +-----------+ | |||
| | | | | (5) Authz Code | | | | | | | (5) Authz Code | | | |||
| | | Client App |----------------------->| Token | | | | Client App |----------------------->| Token | | |||
| | | |<-----------------------| Endpoint | | | | |<-----------------------| Endpoint | | |||
| | +---------------------------+ | (6) Access Token, | | | | +---------------------------+ | (6) Access Token, | | | |||
| | | ^ | Refresh Token +-----------+ | | | ^ | Refresh Token +-----------+ | |||
| | | | | | | | | | | |||
| skipping to change at page 5, line 36 ¶ | skipping to change at page 5, line 41 ¶ | |||
| | | +---------------+ | | | +---------------+ | |||
| +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | |||
| Figure 1: Native App Authorization via External User-agent | Figure 1: Native App Authorization via External User-agent | |||
| Figure 1 illustrates the interaction of the native app with the | Figure 1 illustrates the interaction of the native app with the | |||
| system browser to authorize the user via an external user-agent. | system browser to authorize the user via an external user-agent. | |||
| 1) The client app opens a browser tab with the authorization request. | 1) The client app opens a browser tab with the authorization request. | |||
| 2) Authorization endpoint receives the authorization request, and | 2) Authorization endpoint receives the authorization request, | |||
| processes it, typically by authenticating the end-user and | authenticates the user and obtains authorization. Authenticating | |||
| obtaining an authorization decision. How the authorization server | the user may involve chaining to other authentication systems. | |||
| authenticates the end-user is out of scope for this specification, | ||||
| but can potentially involve chaining to other authentication | ||||
| systems using various authentication protocols. | ||||
| 3) Authorization server issues an authorization code to the redirect | 3) Authorization server issues an authorization code to the redirect | |||
| URI. | URI. | |||
| 4) Client receives the authorization code from the redirect URI. | 4) Client receives the authorization code from the redirect URI. | |||
| 5) Client app presents the authorization code at the Token endpoint. | 5) Client app presents the authorization code at the token endpoint. | |||
| 6) Token endpoint validates the authorization code and issues the | 6) Token endpoint validates the authorization code and issues the | |||
| tokens requested. | tokens requested. | |||
| 5. Using Inter-app URI Communication for OAuth | 5. Using Inter-app URI Communication for OAuth | |||
| Just as URIs are used for OAuth 2.0 [RFC6749] on the web to initiate | Just as URIs are used for OAuth 2.0 [RFC6749] on the web to initiate | |||
| the authorization request and return the authorization response to | the authorization request and return the authorization response to | |||
| the requesting website, URIs can be used by native apps to initiate | the requesting website, URIs can be used by native apps to initiate | |||
| the authorization request in the device's system browser and return | the authorization request in the device's browser and return the | |||
| the response to the requesting native app. | response to the requesting native app. | |||
| By applying the same principles from the web to native apps, we gain | By applying the same principles from the web to native apps, we gain | |||
| similar benefits like the usability of a single sign-on session, and | similar benefits like the usability of a single sign-on session, and | |||
| the security by a separate authentication context. It also reduces | the security of a separate authentication context. It also reduces | |||
| the implementation complexity by reusing the same flows as the web, | the implementation complexity by reusing the same flows as the web, | |||
| and increases interoperability by relying on standards-based web | and increases interoperability by relying on standards-based web | |||
| flows that are not specific to a particular platform. | flows that are not specific to a particular platform. | |||
| It is RECOMMENDED that native apps use the URI-based communication | Native apps MUST use an external user-agent to perform OAuth | |||
| functionality of the operating system to perform OAuth flows in an | authentication requests. This is achieved by opening the | |||
| external user-agent, typically the system browser. | authorization request in the browser (detailed in Section 6), and | |||
| using a redirect URI that will return the authorization response back | ||||
| to the native app, as defined in Section 7. | ||||
| This best practice focuses on the browser as the RECOMMENDED external | ||||
| user-agent for native apps. Other external user-agents, such as a | ||||
| native app provided by the authorization server may meet the criteria | ||||
| set out in this best practice, including using the same redirection | ||||
| URI properties, but their use is out of scope for this specification. | ||||
| options for inter-app communication, offering similar security | ||||
| 6. Initiating the Authorization Request from a Native App | ||||
| The authorization request is created as per OAuth 2.0 [RFC6749], and | ||||
| opened in the user's browser using platform-specific APIs for that | ||||
| purpose. | ||||
| The function of the redirect URI for a native app authorization | ||||
| request is similar to that of a web-based authorization request. | ||||
| Rather than returning the authorization response to the OAuth | ||||
| client's server, the redirect URI used by a native app returns the | ||||
| response to the app. The various options for a redirect URI that | ||||
| will return the code to the native app are documented in Section 7. | ||||
| Any redirect URI that allows the app to receive the URI and inspect | ||||
| its parameters is viable. | ||||
| Some platforms support a browser feature known as in-app browser | Some platforms support a browser feature known as in-app browser | |||
| tabs, where an app can present a tab of the browser within the app | tabs, where an app can present a tab of the browser within the app | |||
| context without switching apps, but still retain key benefits of the | context without switching apps, but still retain key benefits of the | |||
| browser such as a shared authentication state and security context. | browser such as a shared authentication state and security context. | |||
| On platforms where they are supported, it is RECOMMENDED for | On platforms where they are supported, it is RECOMMENDED for | |||
| usability reasons that apps use in-app browser tabs for the | usability reasons that apps use in-app browser tabs for the | |||
| Authorization Request. | Authorization Request. | |||
| It is possible to create an external user-agent for OAuth that is a | 7. Receiving the Authorization Response in a Native App | |||
| native app provided by the authorization server, as opposed to the | ||||
| system browser. This approach shares a lot of similarity with using | ||||
| the system browser as both use URIs for inter-app communication and | ||||
| is able to provide a secure, shared authentication session, and thus | ||||
| MAY be used for secure native OAuth, applying most of the techniques | ||||
| described here. However it is NOT RECOMMENDED due to the increased | ||||
| complexity and requirement for the user to have the AS app installed. | ||||
| While much of the advice and security considerations are applicable | ||||
| to such clients, they are out of scope for this specification. | ||||
| 6. Initiating the Authorization Request | ||||
| The authorization request is created as per OAuth 2.0 [RFC6749], and | ||||
| opened in the system browser. Where the operating system supports | ||||
| in-app browser tabs, those should be preferred over switching to the | ||||
| system browser, to improve usability. | ||||
| The function of the redirect URI for a native app authorization | ||||
| request is similar to that of a web-based authorization request. | ||||
| Rather than returning the authorization code to the OAuth client's | ||||
| server, it returns it to the native app. The various options for a | ||||
| redirect URI that will return the code to the native app are | ||||
| documented in Section 7. Any redirect URI that allows the app to | ||||
| receive the URI and inspect its parameters is viable. | ||||
| 7. Receiving the Authorization Response | There are several redirect URI options available to native apps for | |||
| receiving the authorization response from the browser, the | ||||
| availability and user experience of which varies by platform. | ||||
| There are three main approaches to redirection URIs for native apps: | To fully support this best practice, authorization servers MUST | |||
| custom URI schemes, app-claimed HTTPS URI schemes, and loopback | support the following three redirect URI options. Native apps MAY | |||
| redirects. | use whichever redirect option suits their needs best, taking into | |||
| account platform specific implementation details. | ||||
| 7.1. App-declared Custom URI Scheme Redirection | 7.1. App-declared Custom URI Scheme Redirection | |||
| Most major mobile and desktop computing platforms support inter-app | Many mobile and desktop computing platforms support inter-app | |||
| communication via URIs by allowing apps to register custom URI | communication via URIs by allowing apps to register custom URI | |||
| schemes. When the system browser or another app attempts to follow a | schemes, like "com.example.app:". When the browser or another app | |||
| URI with a custom scheme, the app that registered it is launched to | attempts to load a URI with a custom scheme, the app that registered | |||
| handle the request. This document is only relevant on platforms that | it is launched to handle the request. | |||
| support this pattern. | ||||
| In particular, the custom URI scheme pattern is supported on Android | ||||
| [Android.URIScheme], iOS [iOS.URIScheme], Windows Universal Platform | ||||
| (UWP) [WindowsUWP.URIScheme] and macOS [macOS.URIScheme]. | ||||
| 7.1.1. Using Custom URI Schemes for Redirection | ||||
| To perform an OAuth 2.0 Authorization Request on a supported | To perform an OAuth 2.0 Authorization Request on a supported | |||
| platform, the native app launches the system browser with a normal | platform, the native app launches the browser with a normal OAuth 2.0 | |||
| OAuth 2.0 Authorization Request, but provides a redirection URI that | Authorization Request, but provides a redirection URI that utilizes a | |||
| utilizes a custom URI scheme that is registered by the calling app. | custom URI scheme registered with the operating system by the calling | |||
| app. | ||||
| When the authentication server completes the request, it redirects to | When the authentication server completes the request, it redirects to | |||
| the client's redirection URI like it would any redirect URI, but as | the client's redirection URI like it would any redirect URI, but as | |||
| the redirection URI uses a custom scheme, this results in the OS | the redirection URI uses a custom scheme, this results in the OS | |||
| launching the native app passing in the URI. The native app extracts | launching the native app passing in the URI. The native app then | |||
| the code from the query parameters from the URI just like a web | processes the authorization response like any OAuth client. | |||
| client would, and exchanges the Authorization Code like a regular | ||||
| OAuth 2.0 client. | ||||
| 7.1.2. Custom URI Scheme Namespace Considerations | ||||
| When selecting which URI scheme to associate with the app, apps | ||||
| SHOULD pick a scheme that is globally unique, and which they can | ||||
| assert ownership over. | ||||
| To avoid clashing with existing schemes in use, using a scheme that | ||||
| follows the reverse domain name pattern applied to a domain under the | ||||
| app publishers control is RECOMMENDED. Such a scheme can be based on | ||||
| a domain they control, or the OAuth client identifier in cases where | ||||
| the authorization server issues client identifiers that are also | ||||
| valid DNS subdomains. The chosen scheme MUST NOT clash with any IANA | ||||
| registered scheme [IANA.URISchemes]. You SHOULD also ensure that no | ||||
| other app by the same publisher uses the same scheme. | ||||
| Schemes using reverse domain name notation are hardened against | ||||
| collision. They are unlikely to clash with an officially registered | ||||
| scheme [IANA.URISchemes] or unregistered de-facto scheme, as these | ||||
| generally don't include a period character, and are unlikely to match | ||||
| your domain name in any case. They are guaranteed not to clash with | ||||
| any OAuth client following these naming guidelines in full. | ||||
| Some platforms use globally unique bundle or package names that | ||||
| follow the reverse domain name notation pattern. In these cases, the | ||||
| app SHOULD register that bundle id as the custom scheme. If an app | ||||
| has a bundle id or package name that doesn't match a domain name | ||||
| under the control of the app, the app SHOULD NOT register that as a | ||||
| scheme, and instead create a URI scheme based off one of their domain | ||||
| names. | ||||
| For example, an app whose publisher owns the top level domain name | ||||
| "example.com" can register "com.example.app:/" as their custom | ||||
| scheme. An app whose authorization server issues client identifiers | ||||
| that are also valid domain names, for example | ||||
| "client1234.usercontent.idp.com", can use the reverse domain name | ||||
| notation of that domain as the scheme, i.e. | ||||
| "com.idp.usercontent.client1234:/". Each of these examples are URI | ||||
| schemes which are likely to be unique, and where the publisher can | ||||
| assert ownership. | ||||
| As a counter-example, using a simple custom scheme like "myapp:/" is | 7.1.1. Custom URI Scheme Namespace Considerations | |||
| not guaranteed to be unique and is NOT RECOMMENDED. | ||||
| In addition to uniqueness, basing the URI scheme off a name that is | When choosing a URI scheme to associate with the app, apps MUST use a | |||
| under the control of the app's publisher can help to prove ownership | URI scheme based on a domain name under their control, expressed in | |||
| in the event of a dispute where two apps register the same custom | reverse order, as recommended by Section 3.8 of [RFC7595] for | |||
| scheme (such as if an app is acting maliciously). For example, if | private-use URI schemes. | |||
| two apps registered "com.example.app:", the true owner of | ||||
| "example.com" could petition the app store operator to remove the | ||||
| counterfeit app. This petition is harder to prove if a generic URI | ||||
| scheme was chosen. | ||||
| 7.1.3. Registration of App Redirection URIs | For example, an app that controls the domain name "app.example.com" | |||
| can use "com.example.app:/" as their custom scheme. Some | ||||
| authorization servers assign client identifiers based on domain | ||||
| names, for example "client1234.usercontent.example.net", which can | ||||
| also be used as the domain name for the custom scheme, when reversed | ||||
| in the same manner, for example "net.example.usercontent.client1234". | ||||
| As recommended in Section 3.1.2.2 of OAuth 2.0 [RFC6749], the | URI schemes not based on a domain name (for example "myapp:/") MUST | |||
| authorization server SHOULD require the client to pre-register the | NOT be used, as they are not collision resistant, and don't comply | |||
| redirection URI. This remains true for app redirection URIs that use | with Section 3.8 of [RFC7595]. | |||
| custom schemes. | ||||
| Additionally, authorization servers MAY request the inclusion of | Care must be taken when there are multiple apps by the same publisher | |||
| other platform-specific information, such as the app package or | that each URI scheme is unique within that group. On platforms that | |||
| bundle name, or other information used to associate the app that may | use app identifiers that are also based on reverse order domain | |||
| be useful for verifying the calling app's identity, on operating | names, those can be re-used as the custom URI scheme for the OAuth | |||
| systems that support such functions. | redirect. | |||
| Authorizations servers SHOULD support the ability for native apps to | In addition to the collision resistant properties, basing the URI | |||
| register Redirection URIs that utilize custom URI schemes. | scheme off a domain name that is under the control of the app can | |||
| Authorization servers SHOULD enforce the recommendation in | help to prove ownership in the event of a dispute where two apps | |||
| Section 7.1.2 that apps follow naming guidelines for URI schemes. | claim the same custom scheme (such as if an app is acting | |||
| maliciously). For example, if two apps claimed "com.example.app:", | ||||
| the owner of "example.com" could petition the app store operator to | ||||
| remove the counterfeit app. This petition is harder to prove if a | ||||
| generic URI scheme was used. | ||||
| 7.2. App-claimed HTTPS URI Redirection | 7.2. App-claimed HTTPS URI Redirection | |||
| Some operating systems allow apps to claim HTTPS URLs of their | Some operating systems allow apps to claim HTTPS URLs in their | |||
| domains. When the browser sees such a claimed URL, instead of the | domains. When the browser encounters a claimed URL, instead of the | |||
| page being loaded in the browser, the native app is launched instead | page being loaded in the browser, the native app is launched instead | |||
| with the URL given as input. | with the URL supplied as input. | |||
| Where the operating environment provided app-claimed HTTPS URIs in a | ||||
| usable fashion, these URIs should be used as the OAuth redirect, as | ||||
| they allow the identity of the destination app to be guaranteed by | ||||
| the operating system. | ||||
| Apps on platforms that allow the user to disable this functionality, | App-claimed HTTPS redirect URIs have some advantages in that the | |||
| present it in a user-unfriendly way, or lack it altogether MUST | identity of the destination app is guaranteed by the operating | |||
| fallback to using custom URI schemes. | system. Due to this reason, they SHOULD be used over the other | |||
| redirect choices for native apps where possible. | ||||
| The authorization server MUST allow the registration of HTTPS | App-claimed HTTPS redirect URIs function exactly as normal HTTPS | |||
| redirect URIs for non-confidential native clients to support app- | redirects from the perspective of the authorization server, though it | |||
| claimed HTTPS redirect URIs. | is RECOMMENDED that the authorization server is able to distinguish | |||
| between public native app clients that use app-claimed HTTPS redirect | ||||
| URIs and confidential web clients. A flag in the client registration | ||||
| information that indicates a public native app client is one such | ||||
| method for distinguishing client types. | ||||
| 7.3. Loopback URI Redirection | 7.3. Loopback URI Redirection | |||
| More applicable to desktop operating systems, some environments allow | Desktop operating systems allow native apps to listen on a local port | |||
| apps to create a local HTTP listener on a random port, and receive | for HTTP redirects. This can be used by native apps to receive OAuth | |||
| URI redirects that way. This is an acceptable redirect URI choice | authorization responses on compatible platforms. | |||
| for native apps on compatible platforms. | ||||
| Authorization servers SHOULD support redirect URIs on the loopback IP | Loopback redirect URIs take the form of the loopback IP, any port | |||
| address and HTTP scheme, that is, redirect URIs beginning with | (dynamically provided by the client), and a path component. | |||
| http://127.0.0.1[:port]/, http://::1[:port]/, and | Specifically: "http://127.0.0.1:{port}/{path}", and | |||
| http://localhost[:port]/. Authorization servers supporting this class | "http://[::1]:{port}/{path}". | |||
| of redirect URI MUST allow the client to specify a port of their | ||||
| choice, and SHOULD allow the client to use an arbitrary path | ||||
| component. | ||||
| While both the loopback IP and localhost variants SHOULD be supported | For loopback IP redirect URIs, the authorization server MUST allow | |||
| by the authorization server for completeness, it is RECOMMENDED that | any port to be specified at the time of the request, to accommodate | |||
| apps primarily use the loopback IP variant, as it is less susceptible | clients that obtain an available port from the operating system at | |||
| to misconfigured routing and client side firewalls Note that the HTTP | the time of the request. Other than that, the redirect is be treated | |||
| scheme is acceptable for this category of redirect URIs, as the | like any other. | |||
| request never leaves the device. | ||||
| 8. Security Considerations | 8. Security Considerations | |||
| 8.1. Embedded User-Agents | 8.1. Embedded User-Agents | |||
| Embedded user-agents, commonly implemented with web-views, are an | Embedded user-agents, commonly implemented with web-views, are an | |||
| alternative method for authorizing native apps. They are however | alternative method for authorizing native apps. They are however | |||
| unsafe for use by third-parties by definition. They involve the user | unsafe for use by third-parties by definition. They involve the user | |||
| signing in with their full login credentials, only to have them | signing in with their full login credentials, only to have them | |||
| downscoped to less powerful OAuth credentials. | downscoped to less powerful OAuth credentials. | |||
| skipping to change at page 10, line 41 ¶ | skipping to change at page 9, line 45 ¶ | |||
| authenticated actions as the user. | authenticated actions as the user. | |||
| Encouraging users to enter credentials in an embedded web-view | Encouraging users to enter credentials in an embedded web-view | |||
| without the usual address bar and visible certificate validation | without the usual address bar and visible certificate validation | |||
| features that browsers have makes it impossible for the user to know | features that browsers have makes it impossible for the user to know | |||
| if they are signing in to the legitimate site, and even when they | if they are signing in to the legitimate site, and even when they | |||
| are, it trains them that it's OK to enter credentials without | are, it trains them that it's OK to enter credentials without | |||
| validating the site first. | validating the site first. | |||
| Aside from the security concerns, web-views do not share the | Aside from the security concerns, web-views do not share the | |||
| authentication state with other apps or the system browser, requiring | authentication state with other apps or the browser, requiring the | |||
| the user to login for every authorization request and leading to a | user to login for every authorization request and leading to a poor | |||
| poor user experience. | user experience. | |||
| Due to the above, use of embedded user-agents is NOT RECOMMENDED, | Native apps MUST NOT use embedded user-agents for OAuth to third- | |||
| except where a trusted first-party app acts as the external user- | parties. | |||
| agent for other apps, or provides single sign-on for multiple first- | ||||
| party apps. | ||||
| Authorization servers SHOULD consider taking steps to detect and | Authorization servers MAY take steps to detect and block | |||
| block logins via embedded user-agents that are not their own, where | authorization requests in third-party embedded user-agents. | |||
| possible. | ||||
| 8.2. Protecting the Authorization Code | 8.2. Protecting the Authorization Code | |||
| A limitation of custom URI schemes is that multiple apps can | The redirect URI options documented in Section 7 share the benefit | |||
| typically register the same scheme, which makes it indeterminate as | that only a native app on the same device can receive the | |||
| to which app will receive the Authorization Code Grant. This is not | authorization code, however code interception by a native app other | |||
| an issue for HTTPS redirection URIs (i.e. standard web URLs) due to | than the intended recipient may be possible. | |||
| the fact the HTTPS URI scheme is enforced by the authority (as | ||||
| defined by [RFC3986]), the domain name system, which does not allow | A limitation of using custom URI schemes for redirect URIs is that | |||
| multiple entities to own the same domain. | multiple apps can typically register the same scheme, which makes it | |||
| indeterminate as to which app will receive the Authorization Code | ||||
| Grant. This is not an issue for HTTPS redirection URIs (i.e. | ||||
| standard web URLs) due to the fact the HTTPS URI scheme is enforced | ||||
| by the authority (as defined by [RFC3986]), the domain name system, | ||||
| which does not allow multiple entities to own the same domain. | ||||
| If multiple apps register the same scheme, it is possible that the | If multiple apps register the same scheme, it is possible that the | |||
| authorization code will be sent to the wrong app (generally the | authorization code will be sent to the wrong app (generally the | |||
| operating system makes no guarantee of which app will handle the URI | operating system makes no guarantee of which app will handle the URI | |||
| when multiple register the same scheme). PKCE [RFC7636] details how | when multiple register the same scheme). PKCE [RFC7636] details how | |||
| this limitation can be used to execute a code interception attack | this limitation can be used to execute a code interception attack | |||
| (see Figure 1). This attack vector applies to public clients | (see Figure 1). This attack vector applies to public clients | |||
| (clients that are unable to maintain a client secret) which is | (clients that are unable to maintain a client secret) which is | |||
| typical of most native apps. | typical of most native apps. | |||
| While Section 7.1.2 details ways that this can be mitigated through | While Section 7.1.1 details ways that this can be mitigated through | |||
| policy enforcement (through being able to report and have removed any | policy enforcement (through being able to report and have removed any | |||
| offending apps), we can also protect the authorization code grant | offending apps), we can also protect the authorization code grant | |||
| from being used in cases where it was intercepted. | from being used in cases where it was intercepted. | |||
| The Proof Key for Code Exchange by OAuth Public Clients (PKCE | The Proof Key for Code Exchange by OAuth Public Clients (PKCE | |||
| [RFC7636]) standard was created specifically to mitigate against this | [RFC7636]) standard was created specifically to mitigate against this | |||
| attack. It is a Proof of Possession extension to OAuth 2.0 that | attack. It is a Proof of Possession extension to OAuth 2.0 that | |||
| protects the code grant from being used if it is intercepted. It | protects the code grant from being used if it is intercepted. It | |||
| achieves this by having the client generate a secret verifier which | achieves this by having the client generate a secret verifier which | |||
| it passes in the initial authorization request, and which it must | it passes in the initial authorization request, and which it must | |||
| skipping to change at page 12, line 5 ¶ | skipping to change at page 11, line 8 ¶ | |||
| Both the client and the Authorization Server MUST support PKCE | Both the client and the Authorization Server MUST support PKCE | |||
| [RFC7636] to use custom URI schemes, or loopback IP redirects. | [RFC7636] to use custom URI schemes, or loopback IP redirects. | |||
| Authorization Servers SHOULD reject authorization requests using a | Authorization Servers SHOULD reject authorization requests using a | |||
| custom scheme, or loopback IP as part of the redirection URI if the | custom scheme, or loopback IP as part of the redirection URI if the | |||
| required PKCE parameters are not present, returning the error message | required PKCE parameters are not present, returning the error message | |||
| as defined in Section 4.4.1 of PKCE [RFC7636]. It is RECOMMENDED to | as defined in Section 4.4.1 of PKCE [RFC7636]. It is RECOMMENDED to | |||
| use PKCE [RFC7636] for app-claimed HTTPS redirect URIs, even though | use PKCE [RFC7636] for app-claimed HTTPS redirect URIs, even though | |||
| these are not generally subject to interception, to protect against | these are not generally subject to interception, to protect against | |||
| attacks on inter-app communication. | attacks on inter-app communication. | |||
| 8.3. Phishability of In-App Browser Tabs | 8.3. Loopback Redirect Considerations | |||
| Loopback interface redirect URIs use the "http" scheme (i.e. without | ||||
| TLS). This is acceptable for loopback interface redirect URIs as the | ||||
| HTTP request never leaves the device. | ||||
| Clients should open the loopback port only when starting the | ||||
| authorization request, and close it once the response is returned. | ||||
| While redirect URIs using localhost (i.e. "http://localhost:{port}/" | ||||
| function similarly to loopback IP redirects described in Section 7.3, | ||||
| the use of "localhost" is NOT RECOMMENDED. Opening a port on the | ||||
| loopback interface is more secure as only apps on the local device | ||||
| can connect to it. It is also less susceptible to misconfigured | ||||
| routing, and interference by client side firewalls. | ||||
| 8.4. Registration of App Redirection URIs | ||||
| As recommended in Section 3.1.2.2 of OAuth 2.0 [RFC6749], the | ||||
| authorization server SHOULD require the client to pre-register the | ||||
| complete redirection URI. This applies and is RECOMMENDED for all | ||||
| redirection URIs used by native apps. | ||||
| For Custom URI scheme based redirects, authorization servers SHOULD | ||||
| enforce the requirement in Section 7.1.1 that clients use reverse | ||||
| domain name based schemes. | ||||
| Authorization servers MAY request the inclusion of other platform- | ||||
| specific information, such as the app package or bundle name, or | ||||
| other information used to associate the app that may be useful for | ||||
| verifying the calling app's identity, on operating systems that | ||||
| support such functions. | ||||
| 8.5. OAuth Implicit Flow | ||||
| The OAuth 2.0 Implicit Flow as defined in Section 4.2 of OAuth 2.0 | ||||
| [RFC6749] generally works with the practice of performing the | ||||
| authorization request in the browser, and receiving the authorization | ||||
| response via URI-based inter-app communication. However, as the | ||||
| Implicit Flow cannot be protected by PKCE (which is a recommended in | ||||
| Section 7.1.1), the use of the Implicit Flow with native apps is NOT | ||||
| RECOMMENDED. | ||||
| Tokens granted via the implicit flow also cannot be refreshed without | ||||
| user interaction making the code flow, with refresh tokens the more | ||||
| practical option for native app authorizations that require | ||||
| refreshing. | ||||
| 8.6. Phishability of In-App Browser Tabs | ||||
| While in-app browser tabs provide a secure authentication context, as | While in-app browser tabs provide a secure authentication context, as | |||
| the user initiates the flow from a native app, it is possible for | the user initiates the flow from a native app, it is possible for | |||
| that native app to completely fake an in-app browser tab. | that native app to completely fake an in-app browser tab. | |||
| This can't be prevented directly - once the user is in the native | This can't be prevented directly - once the user is in the native | |||
| app, that app is fully in control of what it can render, however | app, that app is fully in control of what it can render, however | |||
| there are several mitigating factors. | there are several mitigating factors. | |||
| Importantly, such an attack that uses a web-view to fake an in-app | Importantly, such an attack that uses a web-view to fake an in-app | |||
| browser tab will always start with no authentication state. If all | browser tab will always start with no authentication state. If all | |||
| native apps use the techniques described in this best practice, users | native apps use the techniques described in this best practice, users | |||
| will not need to sign-in frequently and thus should be suspicious of | will not need to sign-in frequently and thus should be suspicious of | |||
| any sign-in request when they should have already been signed-in. | any sign-in request when they should have already been signed-in. | |||
| This is true even for authorization servers that require frequent or | This is the case even for authorization servers that require | |||
| occasional re-authentication, as such servers can preserve some user | occasional or frequent re-authentication, as such servers can | |||
| identifiable information from the old request, like the email address | preserve some user identifiable information from the old session, | |||
| or avatar. To help mitigate against phishing, it is RECOMMENDED to | like the email address or profile picture and display that on the re- | |||
| show the user some hint that they were previously logged in, as an | authentication. | |||
| attacking app would not be capable of doing this. | ||||
| Users who are particularly concerned about their security may also | Users who are particularly concerned about their security may also | |||
| take the additional step of opening the request in the system browser | take the additional step of opening the request in the browser from | |||
| from the in-app browser tab, and completing the authorization there, | the in-app browser tab, and completing the authorization there, as | |||
| as most implementations of the in-app browser tab pattern offer such | most implementations of the in-app browser tab pattern offer such | |||
| functionality. This is not expected to be common user behavior, | functionality. | |||
| however. | ||||
| 8.4. Limitations of Non-verifiable Clients | 8.7. Limitations of Non-verifiable Clients | |||
| As stated in Section 10.2 of RFC 6749, the authorization server | As stated in Section 10.2 of OAuth 2.0 [RFC6749], the authorization | |||
| SHOULD NOT process authorization requests automatically without user | server SHOULD NOT process authorization requests automatically | |||
| consent or interaction, except when the identity of the client can be | without user consent or interaction, except when the identity of the | |||
| assured. Measures such as claimed HTTPS redirects can be used by | client can be assured. Measures such as claimed HTTPS redirects can | |||
| native apps to prove their identity to the authorization server, and | be used by native apps to prove their identity to the authorization | |||
| some operating systems may offer alternative platform-specific | server, and some operating systems may offer alternative platform- | |||
| identity features which may be used, as appropriate. | specific identity features which may be used, as appropriate. | |||
| 9. Other External User Agents | 8.8. Non-Browser External User Agents | |||
| This best practice recommends a particular type of external user- | This best practice recommends a particular type of external user- | |||
| agent, the system browser. Other external user-agents patterns may | agent, the user's browser. Other external user-agents patterns may | |||
| also be viable for secure and usable OAuth. This document makes no | also be viable for secure and usable OAuth. This document makes no | |||
| comment on those patterns. | comment on those patterns. | |||
| 10. Client Authentication | 8.9. Client Authentication | |||
| Secrets that are statically included as part of an app distributed to | Secrets that are statically included as part of an app distributed to | |||
| multiple users should not be treated as confidential secrets, as one | multiple users should not be treated as confidential secrets, as one | |||
| user may inspect their copy and learn the secret of all users. For | user may inspect their copy and learn the shared secret. For this | |||
| this reason it is NOT RECOMMENDED for authorization servers to | reason, and those stated in Section 5.3.1 of [RFC6819], it is NOT | |||
| require client authentication of native apps using a secret shared by | RECOMMENDED for authorization servers to require client | |||
| multiple installs of the app, as this serves little value beyond | authentication of native apps using a shared secret, as this serves | |||
| client identification which is already provided by the client_id | little value beyond client identification which is already provided | |||
| request parameter. If an authorization server requires a client | by the "client_id" request parameter. | |||
| secret for native apps, it MUST NOT assume that it is actually | ||||
| secret, unless some method is being used to dynamically provision a | ||||
| unique secret to each installation. | ||||
| 11. References | Authorization servers that still require a shared secret for native | |||
| app clients MUST treat the client as a public client, and not treat | ||||
| the secret as proof of the client's identity. In those cases, it is | ||||
| NOT RECOMMENDED to automatically issue tokens on the basis that the | ||||
| user has previously granted access to the same client, as there is no | ||||
| guarantee that the client is not counterfeit. | ||||
| 11.1. Normative References | 8.10. Cross-App Request Forgery Protections | |||
| [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", | Section 5.3.5 of [RFC6819] recommends using the 'state' parameter to | |||
| RFC 6749, DOI 10.17487/RFC6749, October 2012, | link client requests and responses to prevent CSRF attacks. | |||
| <http://www.rfc-editor.org/info/rfc6749>. | ||||
| [RFC7636] Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key | It is similarly RECOMMENDED for native apps to include a high entropy | |||
| for Code Exchange by OAuth Public Clients", RFC 7636, | secure random number in the 'state' parameter of the authorization | |||
| DOI 10.17487/RFC7636, September 2015, | request, and reject any incoming authorization responses without a | |||
| <http://www.rfc-editor.org/info/rfc7636>. | state value that matches a pending outgoing authorization request. | |||
| 8.11. Authorization Server Mix-Up Mitigation | ||||
| To protect against a compromised or malicious authorization server | ||||
| attacking another authorization server used by the same app, it is | ||||
| RECOMMENDED that a unique redirect URI is used for each different | ||||
| authorization server used by the app (for example, by varying the | ||||
| path component), and that authorization responses are rejected if the | ||||
| redirect URI they were received on doesn't match the redirect URI in | ||||
| a pending outgoing authorization request. | ||||
| Authorization servers SHOULD allow the registration of a specific | ||||
| redirect URI, including path components, and reject authorization | ||||
| requests that specify a redirect URI that doesn't exactly match the | ||||
| one that was registered. | ||||
| 9. IANA Considerations | ||||
| [RFC Editor: please do not remove this section.] | ||||
| Section 7.1 specifies how private-use URI schemes are used for inter- | ||||
| app communication in OAuth protocol flows. This document requires in | ||||
| Section 7.1.1 that such schemes are based on domain names owned or | ||||
| assigned to the app, as recommended in Section 3.8 of [RFC7595]. Per | ||||
| section 6 of [RFC7595], registration of domain based URI schemes with | ||||
| IANA is not required. Therefore, this document has no IANA actions. | ||||
| 10. References | ||||
| 10.1. Normative References | ||||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
| DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
| <http://www.rfc-editor.org/info/rfc2119>. | <http://www.rfc-editor.org/info/rfc2119>. | |||
| [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | |||
| Resource Identifier (URI): Generic Syntax", STD 66, | Resource Identifier (URI): Generic Syntax", STD 66, | |||
| RFC 3986, DOI 10.17487/RFC3986, January 2005, | RFC 3986, DOI 10.17487/RFC3986, January 2005, | |||
| <http://www.rfc-editor.org/info/rfc3986>. | <http://www.rfc-editor.org/info/rfc3986>. | |||
| 11.2. Informative References | [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", | |||
| RFC 6749, DOI 10.17487/RFC6749, October 2012, | ||||
| <http://www.rfc-editor.org/info/rfc6749>. | ||||
| [RFC7595] Thaler, D., Ed., Hansen, T., and T. Hardie, "Guidelines | ||||
| and Registration Procedures for URI Schemes", BCP 35, | ||||
| RFC 7595, DOI 10.17487/RFC7595, June 2015, | ||||
| <http://www.rfc-editor.org/info/rfc7595>. | ||||
| [RFC7636] Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key | ||||
| for Code Exchange by OAuth Public Clients", RFC 7636, | ||||
| DOI 10.17487/RFC7636, September 2015, | ||||
| <http://www.rfc-editor.org/info/rfc7636>. | ||||
| 10.2. Informative References | ||||
| [RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 | [RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 | |||
| Threat Model and Security Considerations", RFC 6819, | Threat Model and Security Considerations", RFC 6819, | |||
| DOI 10.17487/RFC6819, January 2013, | DOI 10.17487/RFC6819, January 2013, | |||
| <http://www.rfc-editor.org/info/rfc6819>. | <http://www.rfc-editor.org/info/rfc6819>. | |||
| [iOS.URIScheme] | [AppAuth.iOSmacOS] | |||
| "Inter-App Communication", July 2016, <https://developer.a | Wright, S., Denniss, W., and others, "AppAuth for iOS and | |||
| pple.com/library/ios/documentation/iPhone/Conceptual/ | macOS", February 2016, <https://github.com/openid/AppAuth- | |||
| iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter- | iOS>. | |||
| AppCommunication.html>. | ||||
| [macOS.URIScheme] | [AppAuth.Android] | |||
| "Launch Services Concepts", July 2016, <https://developer. | McGinniss, I., Denniss, W., and others, "AppAuth for | |||
| apple.com/library/mac/documentation/Carbon/Conceptual/Laun | Android", February 2016, <https://github.com/openid/ | |||
| chServicesConcepts/LSCConcepts/LSCConcepts.html#//apple_re | AppAuth-Android>. | |||
| f/doc/uid/TP30000999-CH202-CIHFEEAD>. | ||||
| [Android.URIScheme] | [SamplesForWindows] | |||
| "Intents and Intent Filters", July 2016, | Denniss, W., "OAuth for Apps: Samples for Windows", July | |||
| <http://developer.android.com/guide/components/ | 2016, <https://github.com/googlesamples/oauth-apps-for- | |||
| intents-filters.html#ires>. | windows>. | |||
| [WindowsUWP.URIScheme] | Appendix A. Server Support Checklist | |||
| "Handle URI activation", July 2016, | ||||
| <https://msdn.microsoft.com/en-us/windows/uwp/launch- | ||||
| resume/handle-uri-activation>. | ||||
| [IANA.URISchemes] | OAuth servers that support native apps should: | |||
| "Uniform Resource Identifier (URI) Schemes", July 2016, | ||||
| <http://www.iana.org/assignments/uri-schemes/ | ||||
| uri-schemes.xhtml>. | ||||
| [ChromeCustomTab] | 1. Support custom URI-scheme redirect URIs. This is required to | |||
| "Chrome Custom Tabs", July 2016, | support mobile operating systems. See Section 7.1. | |||
| <https://developer.chrome.com/multidevice/android/ | ||||
| customtabs>. | ||||
| [SFSafariViewController] | 2. Support HTTPS redirect URIs for use with public native app | |||
| "SafariServices Changes", July 2016, | clients. This is used by apps on advanced mobile operating | |||
| <https://developer.apple.com/library/ios/documentation/ | systems that allow app-claimed HTTPS URIs. See Section 7.2. | |||
| SafariServices/Reference/SFSafariViewController_Ref/>. | ||||
| [Android.AppLinks] | 3. Support loopback IP redirect URIs. This is required to support | |||
| "App Links", July 2015, | desktop operating systems. See Section 7.3. | |||
| <https://developer.android.com/preview/features/app- | ||||
| linking.html>. | ||||
| [CustomTabsService] | 4. Not assume native app clients can keep a secret. If secrets are | |||
| "CustomTabsService", July 2016, | distributed to multiple installs of the same native app, they | |||
| <https://developer.android.com/reference/android/support/ | should not be treated as confidential. See Section 8.9. | |||
| customtabs/CustomTabsService.html>. | ||||
| [UniversalLinks] | 5. Support PKCE. Recommended to protect authorization code grants | |||
| "Universal Links", July 2016, <https://developer.apple.com | transmitted to public clients over inter-app communication | |||
| /library/ios/documentation/General/Conceptual/AppSearch/ | channels. See Section 8.2 | |||
| UniversalLinks.html>. | ||||
| Appendix A. Operating System Specific Implementation Details | Appendix B. Operating System Specific Implementation Details | |||
| Most of this document attempts to lay out best practices in an | Most of this document defines best practices in an generic manner, | |||
| generic manner, referencing technology available on most operating | referencing techniques commonly available in a variety of | |||
| systems. This non-normative section contains OS-specific | environments. This non-normative section contains OS-specific | |||
| implementation details that are accurate at the time of authorship. | implementation details for the generic pattern, that are considered | |||
| accurate at the time of publishing, but may change over time. | ||||
| It is expected that this OS-specific information will change, but | It is expected that this OS-specific information will change, but | |||
| that the overall principles described in this document for using | that the overall principles described in this document for using | |||
| external user-agents will remain valid. | external user-agents will remain valid. | |||
| A.1. iOS Implementation Details | B.1. iOS Implementation Details | |||
| Claimed HTTPS and custom URI scheme redirects are both viable choices | Apps can initiate an authorization request in the browser without the | |||
| for OAuth on iOS. Developers can claim HTTPS links using Universal | user leaving the app, through the SFSafariViewController class which | |||
| Links [UniversalLinks], available since iOS 9, and can use custom URI | implements the browser-view pattern. Safari can be used to handle | |||
| scheme [iOS.URIScheme] redirects for backwards compatibility. | requests on old versions of iOS without SFSafariViewController. | |||
| Clients SHOULD use Universal Links for authorization requests on iOS | ||||
| 9 and beyond, with the custom URI scheme redirect substituted on | ||||
| older versions. In both cases, the app claims the redirect in the | ||||
| application manifest. | ||||
| As a user experience optimisation, since iOS 9, apps can invoke the | To receive the authorization response, both custom URI scheme | |||
| system browser without the user leaving the app through | redirects and claimed HTTPS links (known as Universal Links) are | |||
| SFSafariViewController [SFSafariViewController], which implements the | viable choices, and function the same whether the request is loaded | |||
| browser-view pattern. This class has all the properties of the | in SFSafariViewController or the Safari app. Apps can claim Custom | |||
| system browser, and is an 'external user-agent', even though it is | URI schemes with the "CFBundleURLTypes" key in the application's | |||
| presented within the host app. Regardless of whether the user | property list file "Info.plist", and HTTPS links using the Universal | |||
| completes the request in the system browser (as is their choice), or | Links feature with an entitlement file and an association file on the | |||
| the SFSafariViewController, the return of the token via custom URI | domain. | |||
| scheme or claimed HTTPS link is the same. | ||||
| A.2. Android Implementation Details | Universal Links are the preferred choice on iOS 9 and above due to | |||
| the ownership proof that is provided by the operating system. | ||||
| Claimed HTTPS and custom URI scheme redirects are both viable choices | A complete open source sample is included in the AppAuth for iOS and | |||
| for OAuth on Android. Developers can claim HTTPS links using App | macOS [AppAuth.iOSmacOS] library. | |||
| Links [Android.AppLinks], available since Android 6.0 though browser | ||||
| support varies, and custom URI scheme [Android.URIScheme] redirects | ||||
| are broadly supported. Clients SHOULD support custom URI scheme | ||||
| redirects for broad compatibility and MAY upgrade to using claimed | ||||
| HTTPs redirects in supported environments. For both redirect | ||||
| options, the app claims the redirect in the application manifest. | ||||
| As a user experience optimisation, apps SHOULD try to launch the | B.2. Android Implementation Details | |||
| authorization request in a Custom Tab. Custom Tab is an | ||||
| implementation of the browser-view pattern, providing a secure | ||||
| browser tab displayed in the context of the app. Chrome is an | ||||
| example of a browser that supports [ChromeCustomTab] CustomTabs. | ||||
| Android Browser vendors SHOULD implement the CustomTabsService | Apps can initiate an authorization request in the browser without the | |||
| [CustomTabsService] to provide this functionality to their users. | user leaving the app, through the Android Custom Tab feature which | |||
| implements the browser-view pattern. The user's default browser can | ||||
| be used to handle requests when no browser supports Custom Tabs. | ||||
| A.3. Windows Implementation Details | Android browser vendors should support the Custom Tabs protocol (by | |||
| providing an implementation of the "CustomTabsService" class), to | ||||
| provide the in-app browser tab user experience optimization to their | ||||
| users. Chrome is one such browser that implements Custom Tabs. | ||||
| Apps written on the Universal Windows Platform (UWP) can claim custom | To receive the authorization response, custom URI schemes are broadly | |||
| URI schemes [WindowsUWP.URIScheme] in their application manifest. | supported through Android Implicit Intends. Claimed HTTPS redirect | |||
| This redirect choice will also open the app when the user taps the | URIs through Android App Links are available on Android 6.0 and | |||
| link. The scheme is limited to 39 characters, and may include the | above. Both types of redirect URIs are registered in the | |||
| `.` character. | application's manifest. | |||
| UWP apps can launch the authorization request in the user's default | A complete open source sample is included in the AppAuth for Android | |||
| browser like so: | [AppAuth.Android] library. | |||
| Uri authorizationRequest = ... | B.3. Windows Implementation Details | |||
| var success = Windows.System.Launcher.LaunchUriAsync(authorizationRequest) | ||||
| The loopback IP redirect is a common choice for traditional Desktop | Apps can initiate an authorization request in the user's default | |||
| apps, and listening on a loopback port is permitted by default | browser using platform APIs for this purpose. | |||
| The custom URI scheme redirect is a good choice for Universal Windows | ||||
| Platform (UWP) apps as it will open the app returning the user right | ||||
| back where they were. Known on UWP as URI Activation, the scheme is | ||||
| limited to 39 characters, but may include the "." character, making | ||||
| short reverse domain name based schemes (as recommended in | ||||
| Section 7.1.1) possible. | ||||
| The loopback redirect is the common choice for traditional desktop | ||||
| apps, listening on a loopback interface port is permitted by default | ||||
| Windows firewall rules. | Windows firewall rules. | |||
| Traditional apps can launch the URI in the user's default browser | A complete open source sample is available [SamplesForWindows]. | |||
| like so: | ||||
| string authorizationRequest = ... | B.4. macOS Implementation Details | |||
| System.Diagnostics.Process.Start(authorizationRequest); | ||||
| When using the "Process.Start" method, care must be taken that the | Apps can initiate an authorization request in the user's default | |||
| input is a valid URL, including correct URI encoding of the | browser using platform APIs for this purpose. | |||
| parameters. This is especially important when the URL includes user- | ||||
| supplied information such as a login hint. | ||||
| A.4. macOS Implementation Details | To receive the authorization response, custom URI schemes are are a | |||
| good redirect URI choice on macOS, as the user is returned right back | ||||
| to the app they launched the request from. These are registered in | ||||
| the application's bundle information property list using the | ||||
| "CFBundleURLSchemes" key. Loopback IP redirects are another viable | ||||
| option, and listening on the loopback interface is allowed by default | ||||
| firewall rules. | ||||
| Both the loopback IP and custom URI scheme redirect choices are | A complete open source sample is included in the AppAuth for iOS and | |||
| viable on macOS. Custom URI schemes [macOS.URIScheme] are registered | macOS [AppAuth.iOSmacOS] library. | |||
| in the application manifest. Listening on the loopback IP typically | ||||
| does not require any firewall changes. | ||||
| Apps can launch the authorization request like so: | B.5. Linux Implementation Details | |||
| NSURL *authorizationRequest = ... | Opening the Authorization Request in the user's default browser | |||
| BOOL success = [[NSWorkspace sharedWorkspace] openURL:authorizationRequest]; | requires a distro-specific command, "xdg-open" is one such tool. | |||
| Appendix B. Acknowledgements | The loopback redirect is the recommended redirect choice for desktop | |||
| apps on Linux to receive the authorization response. | ||||
| Appendix C. Acknowledgements | ||||
| The author would like to acknowledge the work of Marius Scurtescu, | The author would like to acknowledge the work of Marius Scurtescu, | |||
| and Ben Wiley Sittler whose design for using custom URI schemes in | and Ben Wiley Sittler whose design for using custom URI schemes in | |||
| native OAuth 2.0 clients formed the basis of Section 7.1. | native OAuth 2.0 clients formed the basis of Section 7.1. | |||
| The following individuals contributed ideas, feedback, and wording | The following individuals contributed ideas, feedback, and wording | |||
| that shaped and formed the final specification: | that shaped and formed the final specification: | |||
| Naveen Agarwal, Brian Campbell, Adam Dawes, Hannes Tschofenig, Ashish | Andy Zmolek, Steven E Wright, Brian Campbell, Paul Madsen, Nat | |||
| Jain, Paul Madsen, Breno de Medeiros, Eric Sachs, Nat Sakimura, Steve | Sakimura, Iain McGinniss, Rahul Ravikumar, Eric Sachs, Breno de | |||
| Wright, Erik Wahlstrom, Andy Zmolek, Sudhi Umarji. | Medeiros, Hannes Tschofenig, Ashish Jain, Erik Wahlstrom, Bill | |||
| Fisher, Sudhi Umarji, Michael B. Jones, Vittorio Bertocci, Paul | ||||
| Grassi, David Waite, Naveen Agarwal, and Adam Dawes. | ||||
| Authors' Addresses | Authors' Addresses | |||
| William Denniss | William Denniss | |||
| 1600 Amphitheatre Pkwy | 1600 Amphitheatre Pkwy | |||
| Mountain View, CA 94043 | Mountain View, CA 94043 | |||
| USA | USA | |||
| Phone: +1 650-253-0000 | ||||
| Email: wdenniss@google.com | Email: wdenniss@google.com | |||
| URI: http://google.com/ | URI: http://wdenniss.com/appauth | |||
| John Bradley | John Bradley | |||
| Ping Identity | Ping Identity | |||
| Phone: +1 202-630-5272 | Phone: +1 202-630-5272 | |||
| Email: ve7jtb@ve7jtb.com | Email: ve7jtb@ve7jtb.com | |||
| URI: http://www.thread-safe.com/ | URI: http://www.thread-safe.com/p/appauth.html | |||
| End of changes. 105 change blocks. | ||||
| 407 lines changed or deleted | 463 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||