draft-ietf-oauth-native-apps-07.txt | draft-ietf-oauth-native-apps-08.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: July 21, 2017 Ping Identity | Expires: September 3, 2017 Ping Identity | |||
January 17, 2017 | March 2, 2017 | |||
OAuth 2.0 for Native Apps | OAuth 2.0 for Native Apps | |||
draft-ietf-oauth-native-apps-07 | draft-ietf-oauth-native-apps-08 | |||
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 user's 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 | |||
skipping to change at page 1, line 35 ¶ | skipping to change at page 1, line 35 ¶ | |||
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 July 21, 2017. | This Internet-Draft will expire on September 3, 2017. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2017 IETF Trust and the persons identified as the | Copyright (c) 2017 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 22 ¶ | skipping to change at page 2, line 22 ¶ | |||
4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | 4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
4.1. Authorization Flow for Native Apps Using the Browser . . 5 | 4.1. Authorization Flow for Native Apps Using the Browser . . 5 | |||
5. Using Inter-app URI Communication for OAuth . . . . . . . . . 6 | 5. Using Inter-app URI Communication for OAuth . . . . . . . . . 6 | |||
6. Initiating the Authorization Request from a Native App . . . 6 | 6. Initiating the Authorization Request from a Native App . . . 6 | |||
7. Receiving the Authorization Response in a Native App . . . . 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 . . . . . . . . . . . . 8 | 7.2. App-claimed HTTPS URI Redirection . . . . . . . . . . . . 8 | |||
7.3. Loopback URI Redirection . . . . . . . . . . . . . . . . 9 | 7.3. Loopback URI Redirection . . . . . . . . . . . . . . . . 9 | |||
8. Security Considerations . . . . . . . . . . . . . . . . . . . 9 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 9 | |||
8.1. Embedded User-Agents . . . . . . . . . . . . . . . . . . 9 | 8.1. Embedded User-Agents . . . . . . . . . . . . . . . . . . 9 | |||
8.2. Protecting the Authorization Code . . . . . . . . . . . . 10 | 8.2. Non-Browser External User-Agents . . . . . . . . . . . . 10 | |||
8.3. Loopback Redirect Considerations . . . . . . . . . . . . 11 | 8.3. Phishability of In-App Browser Tabs . . . . . . . . . . . 10 | |||
8.4. Registration of Native App Clients . . . . . . . . . . . 11 | 8.4. Protecting the Authorization Code . . . . . . . . . . . . 11 | |||
8.5. OAuth Implicit Flow . . . . . . . . . . . . . . . . . . . 12 | 8.5. OAuth Implicit Flow . . . . . . . . . . . . . . . . . . . 12 | |||
8.6. Phishability of In-App Browser Tabs . . . . . . . . . . . 12 | 8.6. Loopback Redirect Considerations . . . . . . . . . . . . 12 | |||
8.7. Limitations of Non-verifiable Clients . . . . . . . . . . 12 | 8.7. Registration of Native App Clients . . . . . . . . . . . 13 | |||
8.8. Non-Browser External User-Agents . . . . . . . . . . . . 13 | 8.8. Client Authentication . . . . . . . . . . . . . . . . . . 13 | |||
8.9. Client Authentication . . . . . . . . . . . . . . . . . . 13 | 8.9. Client Impersonation . . . . . . . . . . . . . . . . . . 14 | |||
8.10. Cross-App Request Forgery Protections . . . . . . . . . . 13 | 8.10. Cross-App Request Forgery Protections . . . . . . . . . . 14 | |||
8.11. Authorization Server Mix-Up Mitigation . . . . . . . . . 13 | 8.11. Authorization Server Mix-Up Mitigation . . . . . . . . . 14 | |||
9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 | 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 | |||
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 14 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
10.1. Normative References . . . . . . . . . . . . . . . . . . 14 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 | |||
10.2. Informative References . . . . . . . . . . . . . . . . . 15 | 10.2. Informative References . . . . . . . . . . . . . . . . . 15 | |||
Appendix A. Server Support Checklist . . . . . . . . . . . . . . 15 | Appendix A. Server Support Checklist . . . . . . . . . . . . . . 16 | |||
Appendix B. Operating System Specific Implementation Details . . 16 | Appendix B. Operating System Specific Implementation Details . . 16 | |||
B.1. iOS Implementation Details . . . . . . . . . . . . . . . 16 | B.1. iOS Implementation Details . . . . . . . . . . . . . . . 17 | |||
B.2. Android Implementation Details . . . . . . . . . . . . . 16 | B.2. Android Implementation Details . . . . . . . . . . . . . 17 | |||
B.3. Windows Implementation Details . . . . . . . . . . . . . 17 | B.3. Windows Implementation Details . . . . . . . . . . . . . 18 | |||
B.4. macOS Implementation Details . . . . . . . . . . . . . . 18 | B.4. macOS Implementation Details . . . . . . . . . . . . . . 18 | |||
B.5. Linux Implementation Details . . . . . . . . . . . . . . 18 | B.5. Linux Implementation Details . . . . . . . . . . . . . . 19 | |||
Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 18 | Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 19 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 18 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
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: an embedded user-agent, or an external user- | authorization endpoint: an embedded user-agent, and an external user- | |||
agent. | agent. | |||
This best current practice recommends that only external user-agents | This best current practice requires that only external user-agents | |||
like the browser are used for OAuth by native apps. It documents how | like the browser are used for OAuth by native apps. It documents how | |||
native apps can implement authorization flows using the browser as | native apps can implement authorization flows using the browser as | |||
the preferred external user-agent, and the requirements for | the preferred external user-agent, and the requirements for | |||
authorization servers to support such usage. | authorization servers to support such usage. | |||
This practice is also known as the AppAuth pattern, in reference to | This practice is also known as the AppAuth pattern, in reference to | |||
open source libraries that implement it. | open source libraries that implement it. | |||
2. Notational Conventions | 2. Notational Conventions | |||
skipping to change at page 4, line 16 ¶ | skipping to change at page 4, line 16 ¶ | |||
part of the operating system, or installed and set as default by | part of the operating system, or installed and set as default by | |||
the user. | the user. | |||
"browser tab" An open page of the browser. Browser typically have | "browser tab" An open page of the browser. Browser typically 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 browser. | full security properties and authentication state of the browser. | |||
Has different platform-specific product names, such as | Has different platform-specific product names, such as | |||
SFSafariViewController on iOS, and Chrome Custom Tab on Android. | SFSafariViewController on iOS, and Custom Tabs on Android. | |||
"inter-app communication" Communication between two apps on a | "inter-app communication" Communication between two apps on a | |||
device. | device. | |||
"claimed HTTPS URL" Some platforms allow apps to claim a HTTPS URL | "claimed HTTPS URL" Some platforms allow apps to claim a HTTPS URL | |||
after proving ownership of the domain name. URLs claimed in such | after proving ownership of the domain name. URLs claimed in such | |||
a way are then opened in the app instead of the browser. | 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 private-use URI scheme defined by the app and | |||
app creates and registers with the OS (and is not a standard URI | registered with the operating system. URI requests to such | |||
scheme like "https:" or "tel:"). Requests to such a scheme | schemes trigger the app which registered it to be launched to | |||
results in the app which registered it being launched by the OS. | handle the request. | |||
"web-view" A web browser UI component that can be embedded in apps | "web-view" A web browser UI component that can be embedded in apps | |||
to render web pages, used to create embedded user-agents. | to render web pages, used to create embedded user-agents. | |||
"reverse domain name notation" A naming convention based on the | "reverse domain name notation" A naming convention based on the | |||
domain name system, but where where the domain components are | domain name system, but where where the domain components are | |||
reversed, for example "app.example.com" becomes "com.example.app". | reversed, for example "app.example.com" becomes "com.example.app". | |||
4. Overview | 4. Overview | |||
skipping to change at page 5, line 16 ¶ | skipping to change at page 5, line 16 ¶ | |||
enables single sign-on, as users don't need to authenticate to the | enables single sign-on, as users don't need to authenticate to the | |||
authorization server each time they use a new app (unless required by | authorization server each time they use a new app (unless required by | |||
authorization server policy). | authorization server policy). | |||
Supporting authorization flows between a native app and the browser | Supporting authorization flows between a native app and the browser | |||
is possible without changing the OAuth protocol itself, as the | is possible without changing the OAuth protocol itself, as the | |||
authorization request and response are already defined in terms of | authorization request and response are already defined in terms of | |||
URIs, which emcompasses URIs that can be used for inter-process | URIs, which emcompasses URIs that can be used for inter-process | |||
communication. Some OAuth server implementations that assume all | communication. Some OAuth server implementations that assume all | |||
clients are confidential web-clients will need to add an | clients are confidential web-clients will need to add an | |||
understanding of native app OAuth clients and the types of redirect | understanding of public native app clients and the types of redirect | |||
URIs they use to support this best practice. | 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 the Browser | |||
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | |||
| User Device | | | User Device | | |||
| | | | | | |||
| +---------------------------+ | +-----------+ | | +---------------------------+ | +-----------+ | |||
| | | | (5) Authz Code | | | | | | | (5) Authz Code | | | |||
| | Client App |----------------------->| Token | | | | Client App |----------------------->| Token | | |||
skipping to change at page 6, line 30 ¶ | skipping to change at page 6, line 30 ¶ | |||
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 browser and return the | the authorization request in the device's browser and return 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 | benefits seen on the web like the usability of a single sign-on | |||
the security of a separate authentication context. It also reduces | session, and the security of a separate authentication context. It | |||
the implementation complexity by reusing the same flows as the web, | also reduces the implementation complexity by reusing similar flows | |||
and increases interoperability by relying on standards-based web | as the web, and increases interoperability by relying on standards- | |||
flows that are not specific to a particular platform. | based web flows that are not specific to a particular platform. | |||
Native apps MUST use an external user-agent to perform OAuth | Native apps MUST use an external user-agent to perform OAuth | |||
authentication requests. This is achieved by opening the | authentication requests. This is achieved by opening the | |||
authorization request in the browser (detailed in Section 6), and | authorization request in the browser (detailed in Section 6), and | |||
using a redirect URI that will return the authorization response back | using a redirect URI that will return the authorization response back | |||
to the native app, as defined in Section 7. | to the native app, as defined in Section 7. | |||
This best practice focuses on the browser as the RECOMMENDED external | This best practice focuses on the browser as the RECOMMENDED external | |||
user-agent for native apps. Other external user-agents, such as a | user-agent for native apps. Other external user-agents, such as a | |||
native app provided by the authorization server may meet the criteria | native app provided by the authorization server may meet the criteria | |||
skipping to change at page 7, line 36 ¶ | skipping to change at page 7, line 36 ¶ | |||
availability and user experience of which varies by platform. | availability and user experience of which varies by platform. | |||
To fully support this best practice, authorization servers MUST | To fully support this best practice, authorization servers MUST | |||
support the following three redirect URI options. Native apps MAY | support the following three redirect URI options. Native apps MAY | |||
use whichever redirect option suits their needs best, taking into | use whichever redirect option suits their needs best, taking into | |||
account platform specific implementation details. | account platform specific implementation details. | |||
7.1. App-declared Custom URI Scheme Redirection | 7.1. App-declared Custom URI Scheme Redirection | |||
Many 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 private-use | |||
schemes, like "com.example.app:". When the browser or another app | custom URI schemes like "com.example.app". When the browser or | |||
attempts to load a URI with a custom scheme, the app that registered | another app attempts to load a URI with a custom scheme, the app that | |||
it is launched to handle the request. | registered it is launched to handle the request. | |||
As the custom URI scheme does not have a naming authority (as defined | ||||
by [RFC3986]), there is only a single slash ("/") after the scheme | ||||
component. The following is a complete example of a redirect URI | ||||
utilizing a custom URI scheme: | ||||
com.example.app:/oauth2redirect/example-provider | ||||
To perform an OAuth 2.0 Authorization Request with a custom URI | To perform an OAuth 2.0 Authorization Request with a custom URI | |||
scheme-based redirect URI, the native app launches the browser with a | scheme redirect URI, the native app launches the browser with a | |||
normal OAuth 2.0 Authorization Request, but provides a redirection | normal OAuth 2.0 Authorization Request, but provides a redirection | |||
URI that utilizes a custom URI scheme registered with the operating | URI that utilizes a custom URI scheme it registered with the | |||
system by the calling app. | operating system. | |||
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 it results in the operating | |||
launching the native app passing in the URI. The native app then | system launching the native app, passing in the URI as a launch | |||
processes the authorization response like any OAuth client. | parameter. The native app then processes the authorization response | |||
like any OAuth client. | ||||
7.1.1. Custom URI Scheme Namespace Considerations | 7.1.1. Custom URI Scheme Namespace Considerations | |||
When choosing a URI scheme to associate with the app, apps MUST use a | When choosing a URI scheme to associate with the app, apps MUST use a | |||
URI scheme based on a domain name under their control, expressed in | URI scheme based on a domain name under their control, expressed in | |||
reverse order, as recommended by Section 3.8 of [RFC7595] for | reverse order, as recommended by Section 3.8 of [RFC7595] for | |||
private-use URI schemes. | private-use URI schemes. | |||
For example, an app that controls the domain name "app.example.com" | For example, an app that controls the domain name "app.example.com" | |||
can use "com.example.app:" as their custom scheme. Some | can use "com.example.app" as their custom scheme. Some authorization | |||
authorization servers assign client identifiers based on domain | servers assign client identifiers based on domain names, for example | |||
names, for example "client1234.usercontent.example.net", which can | "client1234.usercontent.example.net", which can also be used as the | |||
also be used as the domain name for the custom scheme, when reversed | domain name for the custom scheme, when reversed in the same manner, | |||
in the same manner, for example "net.example.usercontent.client1234". | for example "net.example.usercontent.client1234". | |||
URI schemes not based on a domain name (for example "myapp:") MUST | URI schemes not based on a domain name (for example "myapp") MUST NOT | |||
NOT be used, as they are not collision resistant, and don't comply | be used, as they are not collision resistant, and don't comply with | |||
with Section 3.8 of [RFC7595]. | Section 3.8 of [RFC7595]. | |||
Care must be taken when there are multiple apps by the same publisher | Care must be taken when there are multiple apps by the same publisher | |||
that each URI scheme is unique within that group. On platforms that | that each URI scheme is unique within that group. On platforms that | |||
use app identifiers that are also based on reverse order domain | use app identifiers that are also based on reverse order domain | |||
names, those can be re-used as the custom URI scheme for the OAuth | names, those can be re-used as the custom URI scheme for the OAuth | |||
redirect. | redirect. | |||
In addition to the collision resistant properties, basing the URI | In addition to the collision resistant properties, basing the URI | |||
scheme off a domain name that is under the control of the app can | scheme off a domain name that is under the control of the app can | |||
help to prove ownership in the event of a dispute where two apps | help to prove ownership in the event of a dispute where two apps | |||
claim the same custom scheme (such as if an app is acting | claim the same custom scheme (such as if an app is acting | |||
maliciously). For example, if two apps claimed "com.example.app:", | maliciously). For example, if two apps claimed "com.example.app:", | |||
the owner of "example.com" could petition the app store operator to | the owner of "example.com" could petition the app store operator to | |||
remove the counterfeit app. This petition is harder to prove if a | remove the counterfeit app. Such a petition is harder to prove if a | |||
generic URI scheme was used. | 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 in their | Some operating systems allow apps to claim HTTPS URL paths in domains | |||
domains. When the browser encounters a claimed URL, instead of the | they control. When the browser encounters a claimed URL, instead of | |||
page being loaded in the browser, the native app is launched with the | the page being loaded in the browser, the native app is launched with | |||
URL supplied as a launch parameter. | the URL supplied as a launch parameter. | |||
Such claimed HTTPS URIs can be used as OAuth redirect URIs. They are | ||||
indistinguishable from OAuth redirects of web-based clients. An | ||||
example is: | ||||
https://app.example.com/oauth2redirect/example-provider | ||||
App-claimed HTTPS redirect URIs have some advantages in that the | App-claimed HTTPS redirect URIs have some advantages in that the | |||
identity of the destination app is guaranteed by the operating | identity of the destination app is guaranteed by the operating | |||
system. Due to this reason, they SHOULD be used over the other | system. Due to this reason, they SHOULD be used over the other | |||
redirect choices for native apps where possible. | redirect choices for native apps where possible. | |||
App-claimed HTTPS redirect URIs function as normal HTTPS redirects | App-claimed HTTPS redirect URIs function as normal HTTPS redirects | |||
from the perspective of the authorization server, though it is | from the perspective of the authorization server, though as stated in | |||
RECOMMENDED that the authorization server is able to distinguish | Section 8.7, it REQUIRED that the authorization server is able to | |||
between public native app clients that use app-claimed HTTPS redirect | distinguish between public native app clients that use app-claimed | |||
URIs and confidential web clients. A configuration option in the | HTTPS redirect URIs and confidential web clients. | |||
client registration (as documented in Section 8.4) is one method for | ||||
distinguishing client types. | ||||
7.3. Loopback URI Redirection | 7.3. Loopback URI Redirection | |||
Desktop operating systems allow native apps to listen on a local port | Native apps that are able to open a port on the loopback network | |||
for HTTP redirects. This can be used by native apps to receive OAuth | interface without needing special permissions (typically, those on | |||
authorization responses on compatible platforms. | desktop operating systems) can use the loopback network interface to | |||
receive the OAuth redirect. | ||||
Loopback redirect URIs take the form of the loopback IP, any port | Loopback redirect URIs use the HTTP scheme and are constructed with | |||
(dynamically provided by the client), and a path component. | the loopback IP literal and whatever port the client is listening on. | |||
Specifically: "http://127.0.0.1:{port}/{path}" for IPv4, and | That is, "http://127.0.0.1:{port}/{path}" for IPv4, and | |||
"http://[::1]:{port}/{path}" for IPv6. | "http://[::1]:{port}/{path}" for IPv6. An complete example of such a | |||
redirect with a randomly assigned port: | ||||
For loopback IP redirect URIs, the authorization server MUST allow | http://127.0.0.1:56861/oauth2redirect/example-provider | |||
any port to be specified at the time of the request, to accommodate | ||||
The authorization server MUST allow any port to be specified at the | ||||
time of the request for loopback IP redirect URIs, to accommodate | ||||
clients that obtain an available port from the operating system at | clients that obtain an available port from the operating system at | |||
the time of the request. Other than that, the redirect is be treated | the time of the request. | |||
like any other. | ||||
8. Security Considerations | 8. Security Considerations | |||
8.1. Embedded User-Agents | 8.1. Embedded User-Agents | |||
Embedded user-agents are an alternative method for authorizing native | Embedded user-agents are an alternative method for authorizing native | |||
apps. They are however unsafe for use by third-parties to the | apps. They are however unsafe for use by third-parties to the | |||
authorization server by definition, as the app that hosts the | authorization server by definition, as the app that hosts the | |||
embedded user-agent can access the user's full authentication | embedded user-agent can access the user's full authentication | |||
credential, not just the OAuth authorization grant that was intended | credential, not just the OAuth authorization grant that was intended | |||
skipping to change at page 10, line 18 ¶ | skipping to change at page 10, line 34 ¶ | |||
the authentication state with other apps or the browser, requiring | the authentication state with other apps or the browser, requiring | |||
the user to login for every authorization request and leading to a | the user to login for every authorization request and leading to a | |||
poor user experience. | poor user experience. | |||
Native apps MUST NOT use embedded user-agents to perform | Native apps MUST NOT use embedded user-agents to perform | |||
authorization requests. | authorization requests. | |||
Authorization endpoints MAY take steps to detect and block | Authorization endpoints MAY take steps to detect and block | |||
authorization requests in embedded user-agents. | authorization requests in embedded user-agents. | |||
8.2. Protecting the Authorization Code | 8.2. Non-Browser External User-Agents | |||
This best practice recommends a particular type of external user- | ||||
agent, the user's browser. Other external user-agent patterns may | ||||
also be viable for secure and usable OAuth. This document makes no | ||||
comment on those patterns. | ||||
8.3. Phishability of In-App Browser Tabs | ||||
While in-app browser tabs provide a secure authentication context, as | ||||
the user initiates the flow from a native app, it is possible for | ||||
that native app to completely fake an in-app browser tab. | ||||
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 | ||||
there are several mitigating factors. | ||||
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 | ||||
native apps use the techniques described in this best practice, users | ||||
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. | ||||
This is the case even for authorization servers that require | ||||
occasional or frequent re-authentication, as such servers can | ||||
preserve some user identifiable information from the old session, | ||||
like the email address or profile picture and display that on the re- | ||||
authentication. | ||||
Users who are particularly concerned about their security may also | ||||
take the additional step of opening the request in the browser from | ||||
the in-app browser tab, and completing the authorization there, as | ||||
most implementations of the in-app browser tab pattern offer such | ||||
functionality. | ||||
8.4. Protecting the Authorization Code | ||||
The redirect URI options documented in Section 7 share the benefit | The redirect URI options documented in Section 7 share the benefit | |||
that only a native app on the same device can receive the | that only a native app on the same device can receive the | |||
authorization code which limits the attack surface, however code | authorization code which limits the attack surface, however code | |||
interception by a native app other than the intended app may still be | interception by a native app other than the intended app may still be | |||
possible. | possible. | |||
A limitation of using custom URI schemes for redirect URIs is that | A limitation of using custom URI schemes for redirect URIs is that | |||
multiple apps can typically register the same scheme, which makes it | multiple apps can typically register the same scheme, which makes it | |||
indeterminate as to which app will receive the Authorization Code. | indeterminate as to which app will receive the Authorization Code. | |||
skipping to change at page 11, line 12 ¶ | skipping to change at page 12, line 14 ¶ | |||
that intercepted the authorization code would not be in possession of | that intercepted the authorization code would not be in possession of | |||
this secret, rendering the code useless. | this secret, rendering the code useless. | |||
Public native app clients MUST protect the authorization request with | Public native app clients MUST protect the authorization request with | |||
PKCE [RFC7636]. Authorization servers MUST support PKCE [RFC7636] | PKCE [RFC7636]. Authorization servers MUST support PKCE [RFC7636] | |||
for public native app clients. Authorization servers SHOULD reject | for public native app clients. Authorization servers SHOULD reject | |||
authorization requests from native apps that don't use PKCE by | authorization requests from native apps that don't use PKCE by | |||
returning an error message as defined in Section 4.4.1 of PKCE | returning an error message as defined in Section 4.4.1 of PKCE | |||
[RFC7636]. | [RFC7636]. | |||
8.3. Loopback Redirect Considerations | 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 required in | ||||
Section 8.4), 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 which can issue refresh tokens | ||||
the more practical option for native app authorizations that require | ||||
refreshing. | ||||
8.6. Loopback Redirect Considerations | ||||
Loopback interface redirect URIs use the "http" scheme (i.e. without | Loopback interface redirect URIs use the "http" scheme (i.e. without | |||
TLS). This is acceptable for loopback interface redirect URIs as the | TLS). This is acceptable for loopback interface redirect URIs as the | |||
HTTP request never leaves the device. | HTTP request never leaves the device. | |||
Clients should open the loopback port only when starting the | Clients should open the network port only when starting the | |||
authorization request, and close it once the response is returned. | authorization request, and close it once the response is returned. | |||
While redirect URIs using localhost (i.e. "http://localhost:{port}/" | Clients should listen on the loopback network interface only, to | |||
function similarly to loopback IP redirects described in Section 7.3, | avoid interference by other network actors. | |||
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 Native App Clients | 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. Specifying a redirect URI with the loopback IP literal | ||||
rather than localhost avoids inadvertently listening on network | ||||
interfaces other than the loopback interface. It is also less | ||||
susceptible to client side firewalls, and misconfigured host name | ||||
resolution on the user's device. | ||||
Authorization Servers SHOULD have a way to distinguish public native | 8.7. Registration of Native App Clients | |||
app clients from confidential web-clients, as the lack of client | ||||
authentication means they are often handled differently. A | ||||
configuration option to indicate a public native app client is one | ||||
such popular method for achieving this. | ||||
As recommended in Section 3.1.2.2 of OAuth 2.0 [RFC6749], the | Native apps, except when using a mechanism like Dynamic Client | |||
authorization server SHOULD require the client to pre-register the | Registration [RFC7591] to provision per-instance secrets, are | |||
complete redirection URI. This applies and is RECOMMENDED for all | classified as public clients, as defined by Section 2.1 of OAuth 2.0 | |||
redirection URIs used by native apps. | [RFC6749] and MUST be registered with the authorization server as | |||
such. Authorization servers MUST record the client type in the | ||||
client registration details in order to identify and process requests | ||||
accordingly. | ||||
Authorization servers MUST require clients to register their complete | ||||
redirect URI (including the path component), and reject authorization | ||||
requests that specify a redirect URI that doesn't exactly match the | ||||
one that was registered, with the exception of loopback redirects, | ||||
where an exact match is required except for the port URI component. | ||||
For Custom URI scheme based redirects, authorization servers SHOULD | For Custom URI scheme based redirects, authorization servers SHOULD | |||
enforce the requirement in Section 7.1.1 that clients use reverse | enforce the requirement in Section 7.1.1 that clients use reverse | |||
domain name based schemes. | domain name based schemes. | |||
Authorization servers MAY request the inclusion of other platform- | Authorization servers MAY request the inclusion of other platform- | |||
specific information, such as the app package or bundle name, or | specific information, such as the app package or bundle name, or | |||
other information used to associate the app that may be useful for | other information used to associate the app that may be useful for | |||
verifying the calling app's identity, on operating systems that | verifying the calling app's identity, on operating systems that | |||
support such functions. | support such functions. | |||
8.5. OAuth Implicit Flow | 8.8. Client Authentication | |||
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 | ||||
the user initiates the flow from a native app, it is possible for | ||||
that native app to completely fake an in-app browser tab. | ||||
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 | ||||
there are several mitigating factors. | ||||
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 | ||||
native apps use the techniques described in this best practice, users | ||||
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. | ||||
This is the case even for authorization servers that require | Secrets that are statically included as part of an app distributed to | |||
occasional or frequent re-authentication, as such servers can | multiple users should not be treated as confidential secrets, as one | |||
preserve some user identifiable information from the old session, | user may inspect their copy and learn the shared secret. For this | |||
like the email address or profile picture and display that on the re- | reason, and those stated in Section 5.3.1 of [RFC6819], it is NOT | |||
authentication. | RECOMMENDED for authorization servers to require client | |||
authentication of public native apps clients using a shared secret, | ||||
as this serves little value beyond client identification which is | ||||
already provided by the "client_id" request parameter. | ||||
Users who are particularly concerned about their security may also | Authorization servers that still require a statically included shared | |||
take the additional step of opening the request in the browser from | secret for native app clients MUST treat the client as a public | |||
the in-app browser tab, and completing the authorization there, as | client (as defined by Section 2.1 of OAuth 2.0 [RFC6749]), and not | |||
most implementations of the in-app browser tab pattern offer such | accept the secret as proof of the client's identity. Without | |||
functionality. | additional measures, such clients are subject to client impersonation | |||
(see Section 8.9). | ||||
8.7. Limitations of Non-verifiable Clients | 8.9. Client Impersonation | |||
As stated in Section 10.2 of OAuth 2.0 [RFC6749], the authorization | As stated in Section 10.2 of OAuth 2.0 [RFC6749], the authorization | |||
server SHOULD NOT process authorization requests automatically | server SHOULD NOT process authorization requests automatically | |||
without user consent or interaction, except when the identity of the | without user consent or interaction, except when the identity of the | |||
client can be assured. Measures such as claimed HTTPS redirects can | client can be assured. This includes the case where the user has | |||
be used by native apps to prove their identity to the authorization | previously approved an authorization request for a given client id - | |||
server, and some operating systems may offer alternative platform- | unless the identity of the client can be proven, the request SHOULD | |||
specific identity features which may be used, as appropriate. | be processed as if no previous request had been approved. | |||
8.8. Non-Browser External User-Agents | ||||
This best practice recommends a particular type of external user- | ||||
agent, the user's browser. Other external user-agent patterns may | ||||
also be viable for secure and usable OAuth. This document makes no | ||||
comment on those patterns. | ||||
8.9. Client Authentication | ||||
Secrets that are statically included as part of an app distributed to | ||||
multiple users should not be treated as confidential secrets, as one | ||||
user may inspect their copy and learn the shared secret. For this | ||||
reason, and those stated in Section 5.3.1 of [RFC6819], it is NOT | ||||
RECOMMENDED for authorization servers to require client | ||||
authentication of native apps using a shared secret, as this serves | ||||
little value beyond client identification which is already provided | ||||
by the "client_id" request parameter. | ||||
Authorization servers that still require a shared secret for native | Measures such as claimed HTTPS redirects MAY be accepted by | |||
app clients MUST treat the client as a public client, and not treat | authorization servers as identity proof. Some operating systems may | |||
the secret as proof of the client's identity. In those cases, it is | offer alternative platform-specific identity features which MAY be | |||
NOT RECOMMENDED to automatically issue tokens on the basis that the | accepted, as appropriate. | |||
user has previously granted access to the same client, as there is no | ||||
guarantee that the client is not counterfeit. | ||||
8.10. Cross-App Request Forgery Protections | 8.10. Cross-App Request Forgery Protections | |||
Section 5.3.5 of [RFC6819] recommends using the 'state' parameter to | Section 5.3.5 of [RFC6819] recommends using the "state" parameter to | |||
link client requests and responses to prevent CSRF attacks. | link client requests and responses to prevent CSRF attacks. | |||
It is similarly RECOMMENDED for native apps to include a high entropy | It is similarly RECOMMENDED for native apps to include a high entropy | |||
secure random number in the 'state' parameter of the authorization | secure random number in the "state" parameter of the authorization | |||
request, and reject any incoming authorization responses without a | request, and reject any incoming authorization responses without a | |||
state value that matches a pending outgoing authorization request. | state value that matches a pending outgoing authorization request. | |||
8.11. Authorization Server Mix-Up Mitigation | 8.11. Authorization Server Mix-Up Mitigation | |||
To protect against a compromised or malicious authorization server | To protect against a compromised or malicious authorization server | |||
attacking another authorization server used by the same app, it is | attacking another authorization server used by the same app, it is | |||
RECOMMENDED that a unique redirect URI is used for each different | REQUIRED that a unique redirect URI is used for each authorization | |||
authorization server used by the app (for example, by varying the | server used by the app (for example, by varying the path component), | |||
path component), and that authorization responses are rejected if the | and that authorization responses are rejected if the redirect URI | |||
redirect URI they were received on doesn't match the redirect URI in | they were received on doesn't match the redirect URI in a outgoing | |||
a pending outgoing authorization request. | authorization request. | |||
Authorization servers SHOULD allow the registration of a specific | The native app MUST store the redirect uri used in the authorization | |||
redirect URI, including path components, and reject authorization | request with the authorization session data (i.e. along with "state" | |||
requests that specify a redirect URI that doesn't exactly match the | and other related data), and MUST verify that the URI on which the | |||
one that was registered. | authorization response was received exactly matches it. | |||
The requirements of Section 8.7 that authorization servers reject | ||||
requests with URIs that don't match what was registered are also | ||||
required to prevent such attacks. | ||||
9. IANA Considerations | 9. IANA Considerations | |||
[RFC Editor: please do not remove this section.] | [RFC Editor: please do NOT remove this section.] | |||
Section 7.1 specifies how private-use URI schemes are used for inter- | Section 7.1 specifies how private-use URI schemes are used for inter- | |||
app communication in OAuth protocol flows. This document requires in | app communication in OAuth protocol flows. This document requires in | |||
Section 7.1.1 that such schemes are based on domain names owned or | 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 | assigned to the app, as recommended in Section 3.8 of [RFC7595]. Per | |||
section 6 of [RFC7595], registration of domain based URI schemes with | section 6 of [RFC7595], registration of domain based URI schemes with | |||
IANA is not required. Therefore, this document has no IANA actions. | IANA is not required. Therefore, this document has no IANA actions. | |||
10. References | 10. References | |||
skipping to change at page 15, line 12 ¶ | skipping to change at page 16, line 5 ¶ | |||
DOI 10.17487/RFC7636, September 2015, | DOI 10.17487/RFC7636, September 2015, | |||
<http://www.rfc-editor.org/info/rfc7636>. | <http://www.rfc-editor.org/info/rfc7636>. | |||
10.2. Informative References | 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>. | |||
[RFC7591] Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and | ||||
P. Hunt, "OAuth 2.0 Dynamic Client Registration Protocol", | ||||
RFC 7591, DOI 10.17487/RFC7591, July 2015, | ||||
<http://www.rfc-editor.org/info/rfc7591>. | ||||
[AppAuth.iOSmacOS] | [AppAuth.iOSmacOS] | |||
Wright, S., Denniss, W., and others, "AppAuth for iOS and | Wright, S., Denniss, W., and others, "AppAuth for iOS and | |||
macOS", February 2016, <https://github.com/openid/AppAuth- | macOS", February 2016, <https://github.com/openid/AppAuth- | |||
iOS>. | iOS>. | |||
[AppAuth.Android] | [AppAuth.Android] | |||
McGinniss, I., Denniss, W., and others, "AppAuth for | McGinniss, I., Denniss, W., and others, "AppAuth for | |||
Android", February 2016, <https://github.com/openid/ | Android", February 2016, <https://github.com/openid/ | |||
AppAuth-Android>. | AppAuth-Android>. | |||
[SamplesForWindows] | [SamplesForWindows] | |||
Denniss, W., "OAuth for Apps: Samples for Windows", July | Denniss, W., "OAuth for Apps: Samples for Windows", July | |||
2016, <https://github.com/googlesamples/oauth-apps-for- | 2016, <https://github.com/googlesamples/oauth-apps-for- | |||
windows>. | windows>. | |||
Appendix A. Server Support Checklist | Appendix A. Server Support Checklist | |||
OAuth servers that support native apps should: | OAuth servers that support native apps must: | |||
1. Support custom URI-scheme redirect URIs. This is required to | 1. Support custom URI-scheme redirect URIs. This is required to | |||
support mobile operating systems. See Section 7.1. | support mobile operating systems. See Section 7.1. | |||
2. Support HTTPS redirect URIs for use with public native app | 2. Support HTTPS redirect URIs for use with public native app | |||
clients. This is used by apps on advanced mobile operating | clients. This is used by apps on advanced mobile operating | |||
systems that allow app-claimed HTTPS URIs. See Section 7.2. | systems that allow app-claimed HTTPS URIs. See Section 7.2. | |||
3. Support loopback IP redirect URIs. This is required to support | 3. Support loopback IP redirect URIs. This is required to support | |||
desktop operating systems. See Section 7.3. | desktop operating systems. See Section 7.3. | |||
4. Not assume native app clients can keep a secret. If secrets are | 4. Not assume native app clients can keep a secret. If secrets are | |||
distributed to multiple installs of the same native app, they | distributed to multiple installs of the same native app, they | |||
should not be treated as confidential. See Section 8.9. | should not be treated as confidential. See Section 8.8. | |||
5. Support PKCE. Recommended to protect authorization code grants | 5. Support PKCE [RFC7636]. Required to protect authorization code | |||
transmitted to public clients over inter-app communication | grants sent to public clients over inter-app communication | |||
channels. See Section 8.2 | channels. See Section 8.4 | |||
Appendix B. Operating System Specific Implementation Details | Appendix B. Operating System Specific Implementation Details | |||
Most of this document defines best practices in an generic manner, | This document primarily defines best practices in an generic manner, | |||
referencing techniques commonly available in a variety of | referencing techniques commonly available in a variety of | |||
environments. This non-normative section contains OS-specific | environments. This non-normative section documents operating system | |||
implementation details for the generic pattern, that are considered | specific implementation details of the best practice. | |||
accurate at the time of publishing, but may change over time. | ||||
It is expected that this OS-specific information will change, but | The implementation details herein are considered accurate at the time | |||
that the overall principles described in this document for using | of publishing but will likely change over time. It is hoped that | |||
external user-agents will remain valid. | such change won't invalidate the generic principles in the rest of | |||
the document, and those principles should take precedence in the | ||||
event of a conflict. | ||||
B.1. iOS Implementation Details | B.1. iOS Implementation Details | |||
Apps can initiate an authorization request in the browser without the | Apps can initiate an authorization request in the browser without the | |||
user leaving the app, through the SFSafariViewController class which | user leaving the app, through the SFSafariViewController class which | |||
implements the in-app browser tab pattern. Safari can be used to | implements the in-app browser tab pattern. Safari can be used to | |||
handle requests on old versions of iOS without | handle requests on old versions of iOS without | |||
SFSafariViewController. | SFSafariViewController. | |||
To receive the authorization response, both custom URI scheme | To receive the authorization response, both custom URI scheme | |||
End of changes. 52 change blocks. | ||||
188 lines changed or deleted | 226 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |