One document matched: draft-hardt-oauth-01.xml
<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2606 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2606.xml">
<!ENTITY RFC2617 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2617.xml">
<!ENTITY RFC2629 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2629.xml">
<!ENTITY RFC3552 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3552.xml">
<!ENTITY OASIS.saml-core-2.0-os SYSTEM "http://xml.resource.org/public/rfc/bibxml2/reference.OASIS.saml-core-2.0-os.xml">
<!ENTITY I-D.narten-iana-considerations-rfc2434bis SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.narten-iana-considerations-rfc2434bis.xml">
<!ENTITY W3C.REC-html40-19980424 SYSTEM "http://xml.resource.org/public/rfc/bibxml4/reference.W3C.REC-html40-19980424.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="3"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc category="info" docName="draft-hardt-oauth-01" ipr="trust200902">
<front>
<title abbrev="OAuth WRAP">OAuth Web Resource Authorization
Profiles</title>
<author fullname="Dick Hardt" initials="D." role="editor" surname="Hardt">
<organization>Microsoft</organization>
<address>
<email>dick.hardt@gmail.com</email>
</address>
</author>
<author fullname="Allen Tom" initials="A." surname="Tom">
<organization>Yahoo!</organization>
<address>
<email>atom@yahoo-inc.com</email>
</address>
</author>
<author fullname="Brian Eaton" initials="B." surname="Eaton">
<organization>Google</organization>
<address>
<email>beaton@google.com</email>
</address>
</author>
<author fullname="Yaron Goland" initials="Y." surname="Goland">
<organization>Microsoft</organization>
<address>
<email>yarong@microsoft.com</email>
</address>
</author>
<date month="January" year="2010" />
<!-- -->
<area>General</area>
<workgroup>Internet Engineering Task Force</workgroup>
<keyword>template</keyword>
<!-- -->
<abstract>
<t>The OAuth Web Resource Authorization Profiles (OAuth WRAP) allow a
server hosting a Protected Resource to delegate authorization to one or
more authorities. An application (Client) accesses the Protected
Resource by presenting a short lived, opaque, bearer token (Access
Token) obtained from an authority (Authorization Server). There are
Profiles for how a Client may obtain an Access Token when acting
autonomously or on behalf of a User.</t>
</abstract>
</front>
<middle>
<section title="Overview">
<t>As the internet has evolved, there is a growing trend for a variety
of applications (Clients) to access resources through an API over HTTP
or other protocols. Often these resources require authorization for
access and are Protected Resources. The systems that are trusted to make
authorization decisions may be independent from the Protected Resources
for scale and security reasons. The OAuth Web Resource Authorization
Profiles (OAuth WRAP) enable a Protected Resource to delegate the
authorization to access a Protected Resource to one or more trusted
authorities.</t>
<t>Clients that wish to access a Protected Resource first obtain
authorization from a trusted authority (Authorization Server). Different
credentials and profiles can be used to obtain this authorization, but
once authorized, the Client is provided an Access Token, and possible a
Refresh Token to obtain new Access Tokens. The Authorization Server
typically includes authorization information in the Access Token and
digitally signs the Access Token. Protected Resource can verify that an
Access Token received from a Client was issued by a trusted
Authorization Server and is valid. The Protected Resource can then
examine the contents of the Access Token to determine the authorization
that has been granted to the Client.</t>
<section title="Accessing a Protected Resource">
<t>The Access Token is opaque to the Client, and can be any format
agreed to between the Authorization Server and the Protected Resource
enabling existing systems to reuse suitable tokens, or use a standard
token format such as a Simple Web Token or JSON Web Token. Since the
Access Token provides the Client authorization to the Protected
Resource for the life of the Access Token, the Authorization Server
should issue Access Tokens that expire within an appropriate time.
When an Access Token expires, the Client requests a new Access Token
from the Authorization Server, which once again computes the Client's
authorization, and issues a new Access Token. <xref
target="fig1"></xref> below shows the flow between the Client and
Authorization Server (A,B); and then between the Client and Protected
Resource (C,D):</t>
<figure align="center" anchor="fig1">
<artwork align="left"><![CDATA[
+---+ +---------------+
| C |--(A)------ credentials --------->| Authorization |
| l |<-(B)------ Access Token ---------| Server |
| i | +---------------+
| e |
| n | Access Token +-----------+
| t |--(C)----- in HTTP header ------->| Protected |
| |<-(D)------ API response ---------| Resource |
+---+ +-----------+
]]></artwork>
</figure>
<t>In step A, the Client presents credentials to the Authorization
Server in exchange for an Access Token.</t>
<t> A Profile specifies the credentials to be provided in step A, and
how the Client obtains them. This specification defines a number of
Profiles; additional Profiles may be defined to support additional
scenarios. The Profiles in this specification are separated into two
groups: autonomous profiles where the Client as acting for itself, and
user delegation profiles where the Client is acting on behalf of a
User.</t>
</section>
<section title="Autonomous Client Profiles">
<t>The following two Profiles (see <xref
target="autonomous.profiles"></xref>) are recommended for scenarios
involving a Client acting autonomously.</t>
<t>Client Account and Password Profile (<xref target="p1"></xref>): This
is the simplest Profile. The Client is provisioned with an account name
and corresponding password by the Authorization Server. The Client
presents the account name and password to the Access Token URL at the
Authorization Server in exchange for an Access Token. This Profile is
not intended for a Client acting on behalf of a User. See the User
Delegation Profiles.</t>
<t>Assertion Profile (<xref target="p2"></xref>): This profile enables a
Client with a <xref target="OASIS.saml-core-2.0-os">SAML</xref> or other
assertion recognized by the Authorization Server. The Client presents
the assertion to the Access Token URL at the Authorization Server in
exchange for an Access Token. How the Client obtains the assertion is
out of scope of OAuth WRAP.</t>
<t>Access Tokens are short lived bearer tokens. When the Protected
Resource is presented with an expired Access Token by the Client, the
Protected Resource returns an error. The Client presents the assertion
once again to the Authorization Server to obtain a new Access
Token.</t>
</section>
<section title="User Delegation Profiles">
<t>Common scenarios involve the User delegating to a Client to act on
the User's behalf, adding another party (the User) to the protocol. In
these Profiles (see <xref target="user.profiles"></xref>), the Client
receives a Refresh Token when it acquires the first Access Token. When
an Access Token expires, the Client presents the Refresh Token to
acquire a new Access Token. Refresh Tokens are sensitive as they
represent long-lived permissions to access a Protected Resource and
are always transmitted using HTTPS.</t>
<t>Username and Password Profile (<xref target="p3"></xref>): While
the User may use a username and password to authenticate to the
Authorization Server, it is undesirable for the Client to store the
User's username and password. In this profile the User provides their
username and password to an application (Client) they have installed
on their device. The Client presents a Client Identifier, the username
and password (credentials) to the Access Token URL at the
Authorization Server in exchange for an Access Token and a Refresh
Token as depicted in <xref target="fig2"></xref> below.</t>
<figure align="center" anchor="fig2">
<artwork align="left"><![CDATA[
+---+ +---------------+
| C |--(A)------ credentials --------->| Authorization |
| l |<-(B)------ Access Token ---------| Server |
| i | Refresh Token +---------------+
| e |
| n | Access Token +-----------+
| t |--(C)----- in HTTP header ------->| Protected |
| |<-(D)------ API response ---------| Resource |
+---+ +-----------+
]]></artwork>
</figure>
<t>When the Access Token expires, the Client presents the Refresh
Token to the Refresh Token URL at the Authorization Server in exchange
for a new Access Token (<xref target="fig3"></xref>, steps A and B).
The Client then uses the new Access Token to access the Protected
Resource (<xref target="fig3"></xref>, steps C and D).</t>
<figure align="center" anchor="fig3">
<artwork align="left"><![CDATA[
+---+ +---------------+
| C |--(A)----- Refresh Token -------->| Authorization |
| l |<-(B)------ Access Token ---------| Server |
| i | +---------------+
| e |
| n | Access Token +-----------+
| t |--(C)----- in HTTP header ------->| Protected |
| |<-(D)------ API response ---------| Resource |
+---+ +-----------+
]]></artwork>
</figure>
<t>Web App Profile (<xref target="p4"></xref>): It is undesirable for
a User to provide their Authorization Server username and password to
web applications. Additionally, the User may authenticate to the
Authorization Server using other mechanisms than a username and
password. In this profile, a web application (Client) has been
provisioned with a Client Identifier and Client Secret and may have
registered a Callback URL. <xref target="fig4"></xref> below
illustrates the protocol. (A) The Client initiates the protocol by
redirecting the User to the User Authorization URL at the
Authorization Server passing the Client Identifier and the Callback
URL. (B) The Authorization Server authenticates the User, confirms the
User would like to authorize the Client to access the Protected
Resource, and generates a Verification Code. (C) The Authorization
Server then redirects the User to the Callback URL at the Client
passing along the Verification Code.</t>
<figure align="center" anchor="fig4">
<artwork align="left"><![CDATA[
+---------+
| Web App |
| Client |
+---------+
v ^
| |
(A) (C)
| |
\ \
+---------+ +---------------+
| |\---(C)-- Verification Code ----<| |
| User | | Authorization |
| at |<---(B)-- User authenticates --->| Server |
| Browser | | |
| |\---(A)-- Client Identifier ---->| |
+---------+ +---------------+
]]></artwork>
</figure>
<t>Similar to step A in <xref target="fig2"></xref>, the Client then
presents the Client Identifier, Client Secret, Callback URL and
Verification code (credentials) to the Access Token URL at the
Authorization Server for an Access Token and a Refresh Token.</t>
<t>Rich App Profile (<xref target="p5"></xref>): This profile is
suitable when the Client is an application the User has installed on
their device and a web browser is available, but it is undesirable for
the User to provide their username and password to an application, or
the user may not be using a username and password to authenticate to
the Authorization Server.</t>
<t>The Client initiates the protocol by directing the User's browser
to the Authorization URL at the Authorization Server passing the
Client Identifier and potentially a Callback URL. The Authorization
Server authenticates the User, confirms the User would like to
authorize the Client to access the Protected Resource, and generates a
Verification Code. The Verification Code may be communicated back to
the Client in a number of ways:</t>
<t><list style="letters">
<t>the Authorization Server presents the Verification Code to the
User, who is instructed to enter the Verification Code directly in
the Client;</t>
<t>the Client reads the Verification Code from the title of the
web page presented by the Authorization Server;</t>
<t>the Authorization Server redirects the User to the Callback URL
that presents Client specific language for the User to enter the
Verification Code into the Client; or</t>
<t>the Client has registered a custom scheme and the Authorization
Server redirects the browser to the custom scheme that causes the
User's browser to load the Client application with the
Verification Code as a parameter.</t>
</list></t>
<t>Similar to step A in <xref target="fig2"></xref>, the Client then
presents the Client Identifier, Callback URL (if provided) and
Verification code (credentials) to the Access Token URL at the
Authorization Server for an Access Token and a Refresh Token.</t>
</section>
</section>
<section title="Requirements Language">
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in <xref
target="RFC2119"></xref>. Domain name examples use <xref
target="RFC2606"></xref>.</t>
</section>
<section title="Definitions">
<t><list hangIndent="6" style="hanging">
<t hangText="Access Token:">a short lived bearer token issued by the
Authorization Server to the Client. The Access Token is presented by
the Client to the Protected Resource to access protected
resources.</t>
<t hangText="Authorization Server:">an authorization resource that
issues Access Tokens to Clients after successful authorization. May
be the same entity as the Protected Resource.</t>
<t hangText="Client:">an application that would like access to a
Protected Resource. Client Identifier:"> a value used by a Client
to identify itself to the Authorization Server. This may be a human
readable string or an opaque identifier.</t>
<t hangText="Client Secret:">a secret used by a web application
Client to establish ownership of the Client Identifier.</t>
<t hangText="Profile:">a mechanism for a Client to obtain an Access
Token from an Authorization Server.</t>
<t hangText="Protected Resource:">a protected API that allows access
via OAuth WRAP. May be the same entity as the Authorization Server.
Refresh Token:"> a long lived bearer token used by a Client to
acquire an Access Token from an Authorization Server.</t>
<t hangText="User:">an individual who has an account with the
Authorization Server.</t>
<t hangText="Verification Code:">a code used by a Client to verify
the User has authorized the Client to have specific access to a
Protected Resource.</t>
</list></t>
<section title="URLs">
<t><list hangIndent="6" style="hanging">
<t hangText="Access Token URL:">the Authorization Server URL at
which an Access Token is requested by the Client. The URL may
accept a variety of parameters depending on the Profile. A Refresh
Token may also be returned to the Client. This URL MUST be an
HTTPS URL and MUST always be called with POST.</t>
<t hangText="Callback URL:">the Client URL where the User will be
redirected after an authorization request to the Authorization
Server.</t>
<t hangText="Refresh Token URL:">the Authorization Server URL at
which a Refresh Token is presented in exchange for a new Access
Token is requested. This URL MUST be an HTTPS URL and MUST always
be called with POST.</t>
<t hangText="User Authorization URL:">the Authorization Server URL
where the Client redirects the User to make an authorization
request.</t>
</list></t>
</section>
</section>
<section anchor="ProtectedResource" title="Accessing a Protected Resource">
<t>Clients always present an Access Token to access a Protected
Resource. Use of the Authorization header is RECOMMENDED, since HTTP
implementations are aware that Authorization headers have special
security properties and may require special treatment in caches and
logs. Protected Resources SHOULD take precautions to insure that Access
Tokens are not inadvertently logged or captured. In addition to the
methods presented here, the Protected Resource MAY allow the Client to
present the Access Token using any scheme agreed on by the Client and
Protected Resource.</t>
<section title="Access Token">
<t>The exact format of the Access Token is opaque to Clients and is
out of scope of this specification. However, Protected Resources MUST
be able to verify that the Access Token was issued by a trusted
Authorization Server and is still valid. Access Tokens SHOULD
periodically expire. The expiry time of Access Tokens is determined as
an appropriate balance between excessive resource utilization if too
short and unauthorized access if too long.</t>
</section>
<section title="Acquiring an Access Token">
<t>An Authorization Server may support one or more protocol profiles
that enable a Client to obtain an Access Token that can be used to
access a Protected Resource.</t>
<t>Client developers only need to implement the profile(s) that align
with how their application will be deployed and are supported by the
Authorization Server.</t>
<t>Authorization Server developers only need to implement the
profile(s) that are appropriate for them.</t>
<t>Protected Resource developers do not implement a profile as the
Client always interacts with the Protected Resource by presenting an
Access Token.</t>
<t><xref target="ParamCon"></xref> has general information about
parameters passed to and from the Authorization Server.</t>
<t>See <xref target="autonomous.profiles"></xref> for how the Client
acquires an Access Token when acting autonomously, and <xref
target="user.profiles"></xref> for how the Client acquires an Access
Token when acting acting on behalf of a User.</t>
</section>
<section title="Client Calls Protected Resource Using HTTP Header">
<t>The Protected Resource SHOULD enable Clients to access the
Protected Resource by including the Access Token in the HTTP
Authorization header using the OAuth WRAP scheme with the following
parameter:</t>
<t><list style="hanging">
<t hangText="access_token"><vspace /> REQUIRED. The value of the
Access Token</t>
</list></t>
<t>For example, if the Access Token is the string 123456789, the HTTP
header would be:</t>
<figure>
<artwork><![CDATA[
Authorization: WRAP access_token="123456789"
]]></artwork>
</figure>
<t>Note that per section 1.2 of <xref target="RFC2617"></xref> that
the following header is also valid:</t>
<figure>
<artwork><![CDATA[
Authorization: WRAP access_token = 123456789
]]></artwork>
</figure>
<t>If the Access Token has expired or is invalid, the Protected
Resource MUST return:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
</section>
<section title="Client Calls Protected Resource Using URL Query Parameter">
<t>The Protected Resource MAY allow the Client to access protected
resources at the Protected Resource by including the following HTTP
URL query parameter in the URL:</t>
<t><list style="hanging">
<t hangText="access_token"><vspace /> REQUIRED. The value of the
Access Token</t>
</list></t>
<t>If the Access Token has expired or is invalid, the Protected
Resource MUST return:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
</section>
<section title="Client Calls Protected Resource Using Post Parameter">
<t>The Protected Resource MAY allow the Client to access protected
resources at the Protected Resource by including the following
parameter in the body of a HTTP post message formatted as
application/x-www-form-urlencoded per <eref
target="http://www.w3.org/TR/1999/REC-W3C.REC-html40-19980424-19991224/interact/forms.html#h-17.13.4.1">17.13.4</eref>
of <xref target="W3C.REC-html40-19980424">HTML 4.01</xref>:</t>
<t><list style="hanging">
<t hangText="access_token"><vspace /> REQUIRED. The value of the
Access Token</t>
</list></t>
<t>If the Access Token has expired or is invalid, the Protected
Resource MUST return:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
</section>
</section>
<section anchor="autonomous.profiles"
title="Acquiring an Access Token: Autonomous Client Profiles">
<t>These are the profiles the Client uses when acting autonomously.</t>
<section anchor="p1" title="Client Account and Password Profile">
<t>This profile is suitable when the Client is an application calling
the Protected Resource on behalf of an organization and the
Authorization Server accepts account passwords for authentication.
This enables the Authorization Server to use an existing
authentication mechanism. This profile SHOULD NOT be used when the
Client is acting on behalf of a user. Profiles <xref format="counter"
target="p3"></xref>, <xref format="counter" target="p4"></xref> or
<xref format="counter" target="p5"></xref> are RECOMMENDED when a
Client is acting on behalf of a User.</t>
<section title="Provisioning">
<t>Prior to initiating this protocol profile, the Client MUST have
obtained an account name and account password from the Authorization
Server.</t>
</section>
<section anchor="p1request" title="Client Requests Access Token">
<t>The Client makes an HTTPS request to the Authorization Server's
Access Token URL using POST. The request contains the following
parameters:</t>
<t><list style="hanging">
<t hangText="wrap_name"><vspace /> REQUIRED. The account
name.</t>
<t hangText="wrap_password"><vspace /> REQUIRED. The account
password.</t>
<t hangText="wrap_scope"><vspace /> OPTIONAL. The Authorization
Server MAY define authorization scope values for the Client to
include.</t>
<t hangText="Additional parameters"><vspace />Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Successful Access Token Response from Authorization Server">
<t>If successful, the Authorization Server returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Refresh Token and an Access Token in the response body.
The response body contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_refresh_token"><vspace /> REQUIRED. The
Refresh Token.</t>
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
<t>The Client may now use the Access Token to access the Protected
Resource per <xref target="ProtectedResource"></xref></t>
</section>
<section title="Unsuccessful Access Token Response from Authorization Server">
<t>If the Client account name and password are invalid, the
Authorization Server MUST respond with:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client MUST obtain a valid account name and password before
retrying the request.</t>
</section>
<section title="Client Refreshes Access Token">
<t>Authorization Servers SHOULD issue Access Tokens that expire and
require Clients to refresh them. Upon receiving the HTTP 401
response when accessing protected resources per <xref
target="ProtectedResource"></xref>, the Client should request a new
Access Token by repeating <xref target="p1request"></xref></t>
</section>
</section>
<section anchor="p2" title="Assertion Profile">
<section title="Provisioning">
<t>Prior to initiating this protocol profile, the Client MUST have a
mechanism for obtained an assertion from an assertion issuer that
can be presented to the Authorization Server for access to the
Protected Resource.</t>
</section>
<section anchor="p2.assertion" title="Client Obtains Assertion">
<t>The Client obtains an assertion. The process for obtaining the
assertion is defined by the assertion issuer and the Authorization
Server, and is out of scope of this specification.</t>
</section>
<section anchor="p2.request" title="Client Requests Access Token">
<t>The Client makes an HTTPS request to the Authorization Server's
Access Token URL using POST. The request contains the following
parameters:</t>
<t><list style="hanging">
<t hangText="wrap_assertion_format"><vspace /> REQUIRED. The
format of the assertion as defined by the Authorization
Server.</t>
<t hangText="wrap_assertion"><vspace /> REQUIRED. The
assertion.</t>
<t hangText="wrap_scope"><vspace /> OPTIONAL. The Authorization
Server MAY define authorization scope values for the Client to
include</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Successful Access Token Response from Authorization Server">
<t>If successful, the Authorization Server returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Access Token in the response body. The response body
contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
<t>The Client may now use the Access Token to access the Protected
Resource per <xref target="ProtectedResource"></xref>.</t>
</section>
<section title="Unsuccessful Access Token Response from Authorization Server">
<t>If the assertion is not valid, the Authorization Server MUST
respond with:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client MUST obtain a valid assertion by repeating <xref
target="p2.assertion"></xref> before retrying the request.</t>
</section>
<section title="Client Refreshes Access Token">
<t>Authorization Servers SHOULD issue Access Tokens that expire and
require Clients to refresh them. Upon receiving the HTTP 401
response when accessing protected resources per <xref
target="ProtectedResource"></xref>, the Client should request a new
Access Token by repeating <xref target="p2.request"></xref> if the
assertion is still valid, otherwise the Client MUST obtain a new,
valid assertion by repeating <xref
target="p2.assertion"></xref>.</t>
</section>
</section>
</section>
<section anchor="user.profiles"
title="Acquiring an Access Token: User Delegation Profiles">
<t>These are the profiles the Client uses when acting on behalf of a
User.</t>
<section anchor="p3" title="Username and Password Profile">
<t>This profile is suitable where the Client is an application the
User has installed on their computer and the User uses a username and
password to authenticate to the Authorization Server. This profile
enables a Client to act on behalf of the User without having to
permanently store the User's username and password.</t>
<section title="Provisioning">
<t>Prior to initiating this protocol profile, the Authorization
Server MAY have required the Client to have obtained a Client
Identifier from the Authorization Server.</t>
</section>
<section anchor="p3.password"
title="Client Obtains Username and Password">
<t>The Client obtains the User's username and password from the
user. The Client MUST discard the username and password once an
Access Token has been obtained.</t>
</section>
<section anchor="p3.request" title="Client Requests Access Token">
<t>The Client makes an HTTPS request to the Authorization Server's
Access Token URL using POST. The request contains the following
parameters:</t>
<t><list style="hanging">
<t hangText="wrap_client_id"><vspace /> REQUIRED. The Client
Identifier.</t>
<t hangText="wrap_username"><vspace /> REQUIRED. The User's
username.</t>
<t hangText="wrap_password"><vspace /> REQUIRED. The User's
password.</t>
<t hangText="wrap_scope"><vspace /> OPTIONAL. The Authorization
Server MAY define authorization scope values for the Client to
include.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Successful Access Token Response from Authorization Server">
<t>If successful, the Authorization Server returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Access Token in the response body. The response body
contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
<t>The Client MUST discard the User's username and password. The
Client securely stores the Refresh Token for later use. The Client
may now use the Access Token to access the Protected Resource per
<xref target="ProtectedResource"></xref>.</t>
</section>
<section title="Unsuccessful Access Token Response from Authorization Server">
<t>The Authorization Server MUST verify User's username and
password. If the verification fails, the Authorization Server MUST
respond with:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client needs to obtain a valid username and password from the
User per <xref target="p3.password"></xref> before retrying the
request.</t>
</section>
<section title="Verification URL Response from Authorization Server">
<t>If the Authorization Server determines that the Client may be
malicious, the Authorization Server MAY require the Client to
instruct the User to visit a Verification URL. The Authorization
Server communicates its requirement by responding to the Client's
Access Token request with the following:</t>
<figure>
<artwork><![CDATA[
HTTP 400 Bad Request
]]></artwork>
</figure>
<t>and the body of the Authorization Server response contains the
following parameter:</t>
<t><list style="hanging">
<t hangText="wrap_verification_url"><vspace />REQUIRED. The
verification URL that the Client MUST either load in the User's
browser, or display for the User to enter into a browser.</t>
</list></t>
<t>The Client MUST then wait for the User to indicate they have
successfully completed the verification process at the Authorization
Server and attempt to obtain an Access Token Refresh Token per <xref
target="p3.request"></xref> again.</t>
</section>
<section title="CAPTCHA Response from Authorization Server">
<t>If the Authorization Server determines that the Client may be
malicious, the Authorization Server MAY require the Client to have
the User solve a CAPTCHA Puzzle. The Authorization Server
communicates its requirement by responding to the Client's Access
Token request with the following:</t>
<figure>
<artwork><![CDATA[
HTTP 400 Bad Request
]]></artwork>
</figure>
<t>and the body of the Authorization Server response contains the
following parameter:</t>
<t><list style="hanging">
<t hangText="wrap_captcha_url"><vspace />REQUIRED. The URL to
the CAPTCHA puzzle image.</t>
</list></t>
<t>The Client MUST present the User with the CAPTCHA puzzle and
prompt for a solution. The Client then MAY attempt to obtain an
Access Token per <xref target="p3.request"></xref> again, including
the following additional parameter:</t>
<t><list style="hanging">
<t hangText="wrap_captcha_url"><vspace />REQUIRED. The URL to
the CAPTCHA puzzle received from the Authorization Server.</t>
<t hangText="wrap_captcha_solution"><vspace />REQUIRED. The
solution string to the CAPTCHA puzzle as defined by the
Authorization Server.</t>
</list></t>
</section>
<section title="Client Refreshes Access Token">
<t>Refreshing an Access Token is the same in <xref
target="p3"></xref>, <xref target="p4"></xref>, and <xref
target="p5"></xref>. Authorization Servers SHOULD issue Access
Tokens that expire and require Clients to refresh them. Upon
receiving the HTTP 401 response when accessing protected resources
per <xref target="ProtectedResource"></xref>, the Client makes an
HTTPS request to the Authorization Server's Refresh Token URL using
POST. The request contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_refresh_token"><vspace />REQUIRED. The Refresh
Token that was received in <xref target="p3.request"></xref></t>
<t hangText="Additional parameters:"><vspace />Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Successful Access Token Refresh">
<t>If successful, the Authorization Server returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Access Token in the response body. The response body
contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Unsuccessful Access Token Refresh">
<t>The Authorization Server MUST verify the Refresh Token. If the
verification fails, the Authorization Server MUST respond with</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client MUST again request authorization from the User by
prompting for the User's username and password per <xref
target="p3.password"></xref> before retrying the request.</t>
</section>
</section>
<section anchor="p4" title="Web App Profile">
<t>This profile is suitable when the Client is a web application
calling the Protected Resource on behalf of a User. This profile
enables a Client to act on behalf of the User without acquiring a
User's credentials.</t>
<section title="Provisioning">
<t>Prior to initiating this protocol profile, the Client MUST have
obtained a Client Identifier and Client Secret from the
Authorization Server. The Authorization Server MAY have also
required the Client to register the Callback URL.</t>
</section>
<section anchor="p4.authorization"
title="Client Directs the User to the Authorization Server">
<t>The Client initiates an authorization request by redirecting the
User's browser to the Authorization Server's User Authorization URL,
with the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_client_id"><vspace /> REQUIRED. The Client
Identifier.</t>
<t hangText="wrap_callback "><vspace /> REQUIRED. The
Callback URL. An absolute URL to which the Authorization Server
will redirect the User back after the User has approved the
authorization request. Authorization Servers MAY require that
the wrap_callback URL match the previously registered value for
the Client Identifier.</t>
<t hangText="wrap_client_state"><vspace />OPTIONAL. An opaque
value that Clients can use to maintain state associated with
this request. If this value is present, the Authorization Server
MUST return it to the Client's Callback URL.</t>
<t hangText="wrap_scope"><vspace /> OPTIONAL. The Authorization
Server MAY define authorization scope values for the Client to
include.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Authorization Server Confirms Authorization Request with User">
<t>Upon receiving an authorization request from the Client by a
redirection of the User's browser, the Authorization Server
authenticates the user, presents the User with the Protected
Resource access that will be granted to the Client, and prompts the
User to confirm the request.</t>
<t>If the User denies the request, the Authorization Server MAY
allow the User to return to the Client Callback URL with the
following parameters added:</t>
<t><list style="hanging">
<t hangText="wrap_error_reason"><vspace /> REQUIRED. Value is
user_denied</t>
<t hangText="wrap_client_state"><vspace /> REQUIRED if the
Client sent the value in the authorization request in <xref
target="p4.authorization"></xref></t>
</list></t>
<t>If the User approves the request, the Authorization Server
generates a Verification Code and associates it with the Client
Identifier and Callback URL.</t>
</section>
<section title="Authorization Server Directs User back to the Client">
<t>If the User approved the request, the Authorization Server MUST
redirect the User back to the Callback URL, with the following
parameters added:</t>
<t><list style="hanging">
<t hangText="wrap_verification_code"><vspace /> REQUIRED. The
Verification Code.</t>
<t hangText="wrap_client_state"><vspace /> REQUIRED if the
Client sent the value in the authorization request in <xref
target="p4.authorization"></xref></t>
<t hangText="Additional parameters:"><vspace />Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section anchor="p4.request" title="Client Requests Access Token">
<t>The Client makes an HTTPS request to the Authorization Server's
Access Token URL, using POST. The request contains the following
parameters in the body of the request:</t>
<t><list style="hanging">
<t hangText="wrap_client_id"><vspace /> REQUIRED. The Client
Identifier</t>
<t hangText="wrap_client_secret"><vspace />REQUIRED. The Client
Secret</t>
<t hangText="wrap_verification_code"><vspace /> REQUIRED. The
Verification Code.</t>
<t hangText="wrap_callback"><vspace /> REQUIRED. The Callback
URL used to obtain the Verification Code.</t>
<t hangText="Additional parameters:"><vspace />Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Successful Access Token Response from Authorization Server">
<t>After receiving the Access Token request, the Authorization
Server verifies the request as follows:</t>
<t><list>
<t>the Client Secret MUST match the Client Identifer</t>
<t>the Client Identifier MUST match the Client Identifier from
the authorization redirect</t>
<t>the Verification Code MUST match the Client Identifier from
the authorization redirect</t>
<t>the Callback URL MUST match the Callback URL from the
authorization redirect</t>
<t>if the Callback URL or Callback URL pattern was registered
with the Authorization Server, the Callback URL MUST match the
Callback URL or Callback URL pattern as defined by the
Authorization Server</t>
<t>the Verification Code MUST not have expired</t>
</list></t>
<t>The Authorization Server MAY also require that a Verification
Code is not reused.</t>
<t>If verification is successful, the Authorization Server
returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Refresh Token and the Access Token in the response body.
The response body contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_refresh_token"><vspace /> REQUIRED. The
Refresh Token.</t>
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
<t>The Client securely stores the Refresh Token for later use. The
Client may now use the Access Token to access the Protected Resource
per <xref target="ProtectedResource"></xref>.</t>
</section>
<section title="Unsuccessful Access Token Response from Authorization Server">
<t>The Authorization Server MUST first verify the Client Identifier
and Client Secret. If they are invalid, the Authorization Server
MUST respond with:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client MUST obtain a valid Client Identifier and Client
Secret before retrying the request.</t>
<t>The Authorization Server MUST then verify that the Callback URL
and Verification Code are associated with the Client Identifier. If
the verification fails, the Authorization Server MUST respond
with:</t>
<figure>
<artwork><![CDATA[
HTTP 400 Bad Request
]]></artwork>
</figure>
<t>and the body of the Authorization Server response contains the
following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_error_reason"><vspace />OPTIONAL. If all the
parameters are valid except that the Verification Code has
expired or been revoked, then it is RECOMMENDED that this
parameter be included and if so, then the value MUST be:</t>
<t><figure>
<artwork><![CDATA[
expired_verification_code
]]></artwork>
</figure></t>
<t>This enables the Client to detect it needs a new Verification
Code and to direct the User to the Authorization Server per
<xref target="p4.authorization"></xref></t>
<t>If the Callback URL is invalid, the value MUST be:</t>
<t><figure>
<artwork><![CDATA[
invalid_callback
]]></artwork>
</figure></t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Client Refreshes Access Token">
<t>Refreshing an Access Token is the same in <xref
target="p3"></xref>, <xref target="p4"></xref>, and <xref
target="p5"></xref>. Authorization Servers SHOULD issue Access
Tokens that expire and require Clients to refresh them. Upon
receiving the HTTP 401 response when accessing protected resources
per <xref target="ProtectedResource"></xref>, the Client makes an
HTTPS request to the Authorization Server's Refresh Token URL using
POST. The request contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_refresh_token"><vspace />REQUIRED. The Refresh
Token that was received in <xref target="p4.request"></xref></t>
<t hangText="Additional parameters:"><vspace />Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Successful Access Token Refresh">
<t>If successful, the Authorization Server returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Access Token in the response body. The response body
contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Unsuccessful Access Token Refresh">
<t>The Authorization Server MUST verify the Refresh Token. If the
verification fails, the Authorization Server MUST respond with</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client MUST again request authorization from the User per
<xref target="p4.authorization"></xref>.</t>
</section>
</section>
<section anchor="p5" title="Rich App Profile">
<t>This profile is suitable where the Client is an application the
User has installed on their computer and there is a browser available
for the Client to launch. This profile enables a Client to act on
behalf of the User regardless of how the User authenticates to the
Server and without access to the User's credentials.</t>
<section title="Provisioning">
<t>Prior to initiating this protocol profile, the Client MAY be
required to register the Client Identifier and/or the Callback URL
with the Server.</t>
</section>
<section anchor="p5.authorization"
title="Client Directs the User to the Authorization Server">
<t>The Client initiates an authorization request by opening the
User's browser with the Server's User Authorization URL, and
including the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_client_id"><vspace /> REQUIRED. The Client
Identifier.</t>
<t hangText="wrap_callback "><vspace /> OPTIONAL. A Callback
URL where the Authorization Server MAY redirect the User's
browser after the User responds to the authorization
request.</t>
<t hangText="wrap_client_state"><vspace />OPTIONAL. An opaque
value that Clients can use to maintain state associated with
this request. If this value is present, the Authorization Server
MUST return it to the Client's Callback URL.</t>
<t hangText="wrap_scope"><vspace /> OPTIONAL. The Authorization
Server MAY define authorization scope values for the Client to
include.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Authorization Server Confirms Authorization Request with User">
<t>Upon receiving an authorization request from the Client by way of
the User's browser, the Authorization Server authenticates the user,
presents the User with the Protected Resource access that will be
granted to the Client, and prompts the User to confirm the request.
If the User approves the request, the Authorization Server generates
a Verification Code. If the User denied access, the Authorization
Server MAY set the Verification Code to the reserved value:</t>
<figure>
<artwork><![CDATA[
user_denied
]]></artwork>
</figure>
<t>It is RECOMMENDED the Verification Code be single use, and expire
within minutes of issue. There are a number of mechanisms for the
Authorization Server to transmit the Verification Code to the
Client, specified below.</t>
<t>Rich Application interaction with the User and the Authorization
Server is an area of active research and development. If the Rich
Application is able to retrieve the verifier directly from the
callback URL returned by the Authorization Server, an improved user
experience is possible. However, not all applications are able to
interact with the Authorization Server in this manner.</t>
<section title="Applications with Callback URLs">
<t>Rich Applications may be able to receive callback URLs in any
of several ways. For example, the Rich Application may register a
custom protocol handler with the application platform so that the
application will be invoked when the browser is redirected to the
callback URL. Alternatively, the callback URL may point to a web
site with which the Rich Application has a trust relationship. The
web site can then pass the Callback URL down to the Rich
Application for processing. Finally, the Callback URL may point to
a web site that will display the Callback URL to the screen along
with instructions for the user to enter the Verification Code into
the application.</t>
<t>For Rich Applications with a Callback URL, the Authorization
Server MUST redirect the User back to the Callback URL, with the
following parameters added:</t>
<t><list style="hanging">
<t hangText="wrap_verification_code"><vspace /> REQUIRED. The
Verification Code</t>
<t hangText="wrap_client_state"><vspace /> REQUIRED if the
Client sent the value in the authorization request in <xref
target="p5.authorization"></xref></t>
<t hangText="Additional parameters"><vspace /> Any
additional parameters, as defined by the Authorization
Server.</t>
</list></t>
<t>If the User denied access, the Server MAY redirect the User's
browser to the Callback URL with the Verification Code set to the
reserved value:</t>
<figure>
<artwork><![CDATA[
user_denied
]]></artwork>
</figure>
</section>
<section title="Applications without Callback URLs">
<t>Rich Applications without Callback URLs need to receive the
verification code in other ways. For Rich Applications without a
Callback URL, the Authorization Server MUST present the
Verification Code on the web page and instruct the user to enter
it into the Client.</t>
<t>The Server MAY also append the Verification Code to the title
of the HTML page so that Clients that have access to the title of
the browser's current page can obtain the Verification Code
without requiring the User enter the Verification Code into the
Client. The Client can parse the title looking for "code=" and
then the rest of the title is the Verification Code. If adding the
Verification Code to the title of the HTML page, the Server MUST
also include the wrap_client_state parameter if sent from the
Client as the "state=" parameter.</t>
<t>Eg. For example.com where the Verification Code = WF34F7HG and
Client State = NMMGFJJ, the Server would set the title of the page
to something like:</t>
<figure>
<artwork><![CDATA[ <title>Successful delegation, code=WF34F7HG
state=NMMGFJJ</title> ]]></artwork>
</figure>
<t>If the User denied access, the Server MAY append
code=user_denied to the title of the HTML page so that the Client
can detect that the User has denied access.</t>
</section>
</section>
<section anchor="p5.request" title="Client Requests Access Token">
<t>The Client makes an HTTPS request to the Server's Access Token
URL using POST. The request contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_client_id"><vspace /> REQUIRED. The Client
Identifier</t>
<t hangText="wrap_verification_code"><vspace /> REQUIRED. The
Verification Code.</t>
<t hangText="Additional parameters:"><vspace />Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section anchor="p5.verification"
title="Successful Access Token Response from Authorization Server">
<t>The Server checks the Verification Code was previously issued to
the same Client Identifier, has not expired and has not been used.
If these conditions are met, the Server marks the Verification Code
as being used and returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Refresh Token and an Access Token in the response body.
The response body contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_refresh_token"><vspace /> REQUIRED. The
Refresh Token.</t>
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
<t>The Client securely stores the Refresh Token for later use. The
Client may now use the Access Token to access the Protected Resource
per <xref target="ProtectedResource"></xref>.</t>
</section>
<section title="Unsuccessful Access Token Response from Authorization Server">
<t>The Authorization Server MUST first verify the Client Identifier
and Client Secret per <xref target="p5.verification"></xref>. If
they are invalid, the Authorization Server MUST respond with:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client needs to obtain a new Verification Code per <xref
target="p5.authorization"></xref>.</t>
</section>
<section title="Client Refreshes Access Token">
<t>Refreshing an Access Token is the same in <xref
target="p3"></xref>, <xref target="p4"></xref>, and <xref
target="p5"></xref>. Authorization Servers SHOULD issue Access
Tokens that expire and require Clients to refresh them. Upon
receiving the HTTP 401 response when accessing protected resources
per <xref target="ProtectedResource"></xref>, the Client makes an
HTTPS request to the Authorization Server's Refresh Token URL using
POST. The request contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_refresh_token"><vspace />REQUIRED. The Refresh
Token that was received in <xref target="p5.request"></xref></t>
<t hangText="Additional parameters:"><vspace />Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Successful Access Token Refresh">
<t>If successful, the Authorization Server returns:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>with the Access Token in the response body. The response body
contains the following parameters:</t>
<t><list style="hanging">
<t hangText="wrap_access_token"><vspace /> REQUIRED. The Access
Token.</t>
<t hangText="wrap_access_token_expires_in"><vspace /> OPTIONAL.
The lifetime of the Access Token in seconds. For example, 3600
represents one hour.</t>
<t hangText="Additional parameters"><vspace /> Any additional
parameters, as defined by the Authorization Server.</t>
</list></t>
</section>
<section title="Unsuccessful Access Token Refresh">
<t>The Authorization Server MUST verify the Refresh Token. If the
verification fails, the Authorization Server MUST respond with</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client MUST again request authorization from the User per
<xref target="p5.authorization"></xref>.</t>
</section>
</section>
</section>
<section anchor="ParamCon" title="Parameter Considerations">
<section title="Authorization Server Request / Response Parameter Encoding">
<t>All requests made directly to the Authorization Server use the HTTP
POST method and the parameters MUST be in the body of the message and
formatted as application/x-www-form-urlencoded per <eref
target="http://www.w3.org/TR/1999/REC-W3C.REC-html40-19980424-19991224/interact/forms.html#h-17.13.4.1">17.13.4</eref>
of <xref target="W3C.REC-html40-19980424">HTML 4.01</xref>.</t>
<t>Any parameters in the response from the Authorization Server MUST
be in the body of the message and formatted as
application/x-www-form-urlencoded per <eref
target="http://www.w3.org/TR/1999/REC-W3C.REC-html40-19980424-19991224/interact/forms.html#h-17.13.4.1">17.13.4</eref>
of <xref target="W3C.REC-html40-19980424">HTML 4.01</xref>.</t>
</section>
<section title="Parameter Size">
<t><list style="hanging">
<t hangText="HTTP Headers"><vspace /> Web servers often impose a
maximum on the combined size of all HTTP headers ranging from 8KB
to 16KB. The size of the Access Token should be small enough to
ensure the total size of the HTTP headers does not exceed the
limits of web servers.</t>
<t hangText="URLs"><vspace /> Web servers and browsers often
impose a maximum on the total length of the URL of as low as 2083
bytes. The length of URLs exposed by the Authorization Server and
the length of parameters passed on a URL should be minimized so
that the total length does not exceed this limit.</t>
</list></t>
</section>
<section title="Access Token Format">
<t>OAuth WRAP does not specify the format of the Access Token. The
format is mutually agreed to by the Authorization Server and the
Protected Resource and is opaque to the Client. The Access Token
format MUST consist of legal characters in an HTTP header per
[Reference needed]</t>
<t>The Simple Web Token (SWT) and JSON Web Token (JWT) are possible
Access Token formats.</t>
<t>[TBD: entropy recommendations for Access Token so that it remains
secure during its lifetime]</t>
</section>
<section title="Refresh Token Format">
<t>OAuth WRAP does not specify the format of the Refresh Token. The
Refresh Token is both generated and consumed by the Authorization
Server and is opaque to the Client and never exposed to the Protected
Resource. The Refresh Token is a long lived credential, and should
contain enough entropy that it cannot be guessed. The size limitations
of the Access Token are not applicable to the Refresh Token as the
Refresh Token is always in the body of an HTTP message.</t>
</section>
<section title="Additional Authorization Server Parameters">
<t>The Authorization Server may define additional parameters to be
included in are returned from calls to the Access Token URL or User
Authorization URL. Parameters that start with wrap_ are reserved and
may not be used.</t>
</section>
<section title="Parameter Names and Order">
<t>All parameter names are case sensitive. The parameters my appear in
any order. Unrecognized parameters are allowed, but MUST be
ignored.</t>
</section>
</section>
<section anchor="IANA" title="IANA Considerations">
<t>This memo includes no request to IANA.</t>
</section>
<section anchor="Security" title="Security Considerations">
<t>TBD: need to put in all the security considerations for
implementors.</t>
</section>
</middle>
<back>
<references title="Normative References">
&RFC2119;
&RFC2606;
&RFC2617;
&W3C.REC-html40-19980424;
</references>
<references title="Informative References">
&I-D.narten-iana-considerations-rfc2434bis;
&OASIS.saml-core-2.0-os;
<reference anchor="OAuth Core 1.0">
<front>
<title>OAuth Core 1.0 Protocol</title>
<author fullname="Eran Hammer-Lahav" initials="E."
surname="Hammer-Lahav">
<organization />
</author>
</front>
<format target="http://tools.ietf.org/html/draft-hammer-oauth-08" type="HTML" />
</reference>
</references>
<section title="Client Account and Password Profile Example">
<t>In this example, crm.example.com is an application server that has a
Protected Resource at https://crm.example.com/data. DataDumper is an
application acting as a Client that periodically calls
https://crm.example.com/data. The Protected Resource trusts the
Authorization Server auth.example.net to determine if a Client has
access.</t>
<section title="Provisioning">
<t>The Authorization Server documentation defines the Access Token URL
as:</t>
<figure>
<artwork><![CDATA[
https://auth.example.net/access_token
]]></artwork>
</figure>
<t>The Authorization Server has defined that the parameter Audience be
included in calls to the Access Token URL.</t>
<t>The Client has been provisioned with the following:</t>
<figure>
<artwork><![CDATA[
Client Account: datadumper Client Password: j2hw7GPsl0
]]></artwork>
</figure>
<t>The Protected Resource and the Authorization Server have agreed to
use a Simple Web Token (SWT) for the Access Token with the reserved
attributes Issuer, Audience, ExpiresOn and the public attribute
net.example.auth.account and have exchanged the following HMAC key
value (expressed in base 64):</t>
<figure>
<artwork><![CDATA[
3iK5ZYAoBQuOqSgF/YqlDw70HKRmbyXkrl5f4SJ4Toc=
]]></artwork>
</figure>
</section>
<section title="Client Requests Access Token">
<t>The Client makes an HTTPS POST to:</t>
<figure>
<artwork><![CDATA[
https://auth.example.net/access_token
]]></artwork>
</figure>
<t>With the following message body:</t>
<figure>
<artwork><![CDATA[
wrap_name=datadumper&wrap_password=j2hw7GPsl0&Audience=crm.example.com
]]></artwork>
</figure>
</section>
<section title="Successful Access Token Response from Authorization Server">
<t>The Authorization Server checks that the Client Password j2hw7GPsl0
is associated with the Client Name datadumper and that the Client is
authorized to access crm.example.com. The Authorization Server notes
the time is 2010-02-03T04:05:06Z, which is 1265198706 seconds since
1970-01-01T0:0:0Z. The Authorization Server would like the Access
Token to expire in an hour, so 3600 is added to the current time. The
Authorization Server then uses the values:</t>
<figure>
<artwork><![CDATA[
net.example.auth.account:
datadumper ExpiresOn: 1265202306 (1265198706 + 3600)
Audience: crm.example.com
Issuer: auth.example.net
]]></artwork>
</figure>
<t>and the agreed HMAC key to generate the following SWT:</t>
<figure>
<artwork><![CDATA[
net.example.auth.account=datadumper&ExpiresOn=1265202306&Audience=crm.
example.com&Issuer=auth.example.net&HMACSHA256=N9%2F%2F0tSos78Me36%2Bi
oBH0sFKfd7eCsURlEIheoUbCJk%3D
]]></artwork>
</figure>
<t>The Authorization Server then responds to the Clients HTTPS request
with:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>and the Access Token and lifetime of the Access Token as
application/x-www-form-urlencoded data in the body of the message as
such:</t>
<figure>
<artwork><![CDATA[
wrap_access_token=net.example.auth.account%3Ddatadumper%26ExpiresOn%3D
1265202306%26Audience%3Dcrm.example.com%26Issuer%3Dauth.example.net%26
HMACSHA256%3DN9%252F%252F0tSos78Me36%252BioBH0sFKfd7eCsURlEIheoUbCJk%2
53D&wrap_access_token_expires_in=3600]]></artwork>
</figure>
</section>
<section title="Client Calls Protected Resource">
<t>The Client now has an Access Token valid for an hour. The Client
makes an API call to:</t>
<figure>
<artwork><![CDATA[
https://crm.example.com/data
]]></artwork>
</figure>
<t>including the following HTTP header:</t>
<figure>
<artwork><![CDATA[
Authorization: WRAP access_token="net.example.auth.account=datadumper&
ExpiresOn=1265202306&Audience=crm.example.com&Issuer=auth.example.net&
HMACSHA256=N9%2F%2F0tSos78Me36%2BioBH0sFKfd7eCsURlEIheoUbCJk%3D"
]]></artwork>
</figure>
<t>The Protected Resources verifies the SWT and performs the Client's
request per the authorization attributes in the SWT.</t>
</section>
</section>
<section title="Web App Profile Example">
<t>In this example, Jane, the User, listens to music from
music.example.com and updates her status at status.example.com. When
listening to music, Jane would like her status to be updated at the
start of each song. From an OAuth WRAP perspective, the Client is
music.example.com, the Protected Resource is
https://status.example.com/update, and auth.example.com is the
Authorization Server trusted by status.example.com.</t>
<section title="Provisioning">
<t>The Authorization Server documentation defines the following
URLs:</t>
<figure>
<artwork><![CDATA[
User Authorization URL: https://auth.example.com/user_authorization
Access Token URL: https://auth.example.com/access_token
Refresh Token URL: https://auth.example.com/refresh_token
]]></artwork>
</figure>
<t>The Authorization Server has defined that if the Client wants
authorization to update a User's status, that the Client include the
wrap_scope parameter with the value status_update when requesting
authorization.</t>
<t>The Client has been provisioned with:</t>
<figure>
<artwork><![CDATA[
Client Identifier: music.example.com
Client Secret: 7F2986DF2342914A
]]></artwork>
</figure>
<t>The Client has registered the Callback URL:</t>
<figure>
<artwork><![CDATA[
https://music.example.com/auth_callback
]]></artwork>
</figure>
<t>The Protected Resource and the Authorization Server have agreed to
use a Simple Web Token (SWT) for the Access Token with the reserved
attributes Issuer, Audience, ExpiresOn and the public attributes
com.example.auth.account, com.example.auth.client and
com.example.auth.scope. They have exchanged the following HMAC key
value (expressed in base 64):</t>
<figure>
<artwork><![CDATA[
Zt9JlL1QvPYRSCK9PgSjrxRUBWe7lbEYsZCdM+sJCF4=
]]></artwork>
</figure>
</section>
<section title="Client Directs the User to the Server">
<t>Jane informs music.example.com that she would like her status at
status.example.com to be updated when a new song starts playing. The
music.example.com website maintains user sessions with a URL parameter
named session which has the value Vn3IG2FRALSEQX2Nxr at this time for
Jane. The Client will use wrap_client_state to maintain the session
value. The Client redirects Jane's browser to the Authorization
Server's User Authorization URL appending parameters for the Client
Identifier, Callback URL, Client state and authorization scope.</t>
<figure>
<artwork><![CDATA[
https://auth.example.com/user_authorization?wrap_client_id=music.examp
le.com&wrap_callback=http%3A%2F%2Fmusic.example.com%2Fauth_callback&wr
ap_client_state=Vn3IG2FRALSEQX2Nxr&wrap_scope=status_update
]]></artwork>
</figure>
</section>
<section title="Authorization Server Confirms Delegation Request with User">
<t>The Authorization Server verifies the supplied Client Identifier
music.example.com has been registered and has the Callback URL
https://music.example.com/auth_callback. The Authorization Server
authenticates that the User it is dealing with is Jane, and then asks
Jane to authorize music.example.com to update Jane's status at
status.example.com. Jane approves the request and the Authorization
Server generates a Verification Code with the value 46YEXQjVit6T3nQ8,
stores it with the Client Identifier, Callback URl and the current
time.</t>
</section>
<section title="Server Directs User back to the Client">
<t>The Server redirects Jane back to the Client's Callback URL with
the Verification Code and Client State appended:</t>
<figure>
<artwork><![CDATA[
https://music.example.com/auth_callback?wrap_verification_code=46YEXQj
Vit6T3nQ8&wrap_client_state=Vn3IG2FRALSEQX2Nxr
]]></artwork>
</figure>
</section>
<section title="Client Requests Access Token">
<t>The Client makes an HTTPS POST request to:</t>
<figure>
<artwork><![CDATA[
https://auth.example.com/access_token
]]></artwork>
</figure>
<t>With the following message body:</t>
<figure>
<artwork><![CDATA[
wrap_client_id=music.example.com&wrap_client_secret=7F2986DF2342914A&w
rap_verification_code=46YEXQjVit6T3nQ8&wrap_callback=http%3A%2F%2Fmusi
c.example.com%2Fauth_callback
]]></artwork>
</figure>
</section>
<section title="Successful Access Token Response from Authorization Server">
<t>The Authorization Server verifies that the Verification Code is
still valid, has not been used, and is associated with the Client ID,
Client Secret and Callback URL Password. The Authorization Server then
generates a Refresh Token with the value:</t>
<figure>
<artwork><![CDATA[
MfdWTc+v9MXhpc+d/csrKFMPfj1RySm6CzIjmTBGN6w=
]]></artwork>
</figure>
<t>The Authorization Server notes the time is 2010-01-02T03:04:05Z,
which is 1262430245 seconds since 1970-01-01T0:0:0Z. The Authorization
Server then uses the values:</t>
<figure>
<artwork><![CDATA[
com.example.auth.scope: status_updatea
com.example.auth.account: Jane
com.example.auth.client: music.example.com
ExpiresOn: 1262433845 (1262430245 + 3600 seconds later)
Audience: status.example.com
Issuer: auth.example.com
]]></artwork>
</figure>
<t>and the agreed HMAC key to generate the following SWT:</t>
<figure>
<artwork><![CDATA[
com.example.auth.scope=status_update&com.example.auth.account=Jane&com
.example.auth.client=music.example.com&ExpiresOn=1262433845&Audience=s
tatus.example.com&Issuer=auth.example.com&HMACSHA256=3xZAYzJRtYCQgkAF3
iqElp1DhyKkPhq947j04NcDocQ%3D
]]></artwork>
</figure>
<t>The Authorization Server then responds to the Clients HTTPS request
with:</t>
<figure>
<artwork><![CDATA[
HTTP 200 OK
]]></artwork>
</figure>
<t>and the Refresh Token, Access Token and lifetime of the Access
Token as application/x-www-form-urlencoded data in the body of the
message as such:</t>
<figure>
<artwork><![CDATA[
wrap_refresh_token=MfdWTc%2Bv9MXhpc%2Bd%2FcsrKFMPfj1RySm6CzIjmTBGN6w%3
D&wrap_access_token=com.example.auth.scope%3Dstatus_update%26com.examp
le.auth.account%3DJane%26com.example.auth.client%3Dmusic.example.com%2
6ExpiresOn%3D1262433845%26Audience%3Dstatus.example.com%26Issuer%3Daut
h.example.com%26HMACSHA256%3D3xZAYzJRtYCQgkAF3iqElp1DhyKkPhq947j04NcDo
cQ%253D&wrap_access_token_expires_in=3600
]]></artwork>
</figure>
<t>The Client now has a Refresh Token and Access Token valid for an
hour. The Client stores the Refresh Token for later use.</t>
</section>
<section title="Client Calls Protected Resource">
<t>A few minutes later, music.example.com starts playing a new song
for Jane. The Client updates Jane's status at status.example.com by
making an API call to:</t>
<figure>
<artwork><![CDATA[
https://status.example.com/update
]]></artwork>
</figure>
<t>including the following HTTP header:</t>
<figure>
<artwork><![CDATA[
Authorization: WRAP access_token="com.example.auth.scope=status_update
&com.example.auth.account=Jane&com.example.auth.client=music.example.c
om&ExpiresOn=1262433845&Audience=status.example.com&Issuer=auth.exampl
e.com&HMACSHA256=3xZAYzJRtYCQgkAF3iqElp1DhyKkPhq947j04NcDocQ%3D"
]]></artwork>
</figure>
<t>The Protected Resources verifies the SWT, confirms the
authorization contained in the SWT, and updates Jane's status.</t>
</section>
<section title="Client Refreshes Access Token">
<t>An hour passes by and music.example.com starts playing another new
song for Jane. The Client again makes an API call to
status.example.com including the same HTTP Authorization header.
Unlike previous calls where the status update was performed, the
Protected Resource returns the following error response:</t>
<figure>
<artwork><![CDATA[
HTTP 401 Unauthorized
]]></artwork>
</figure>
<t>and the HTTP header:</t>
<figure>
<artwork><![CDATA[
WWW-Authenticate: WRAP
]]></artwork>
</figure>
<t>The Client determines it probably needs a new Access Token,
retrieves the Refresh Token and makes an HTTPS POST to:</t>
<figure>
<artwork><![CDATA[
https://auth.example.com/refresh_token
]]></artwork>
</figure>
<t>including the Client Identifier, Client Secret and Refresh Token in
the message body as:</t>
<figure>
<artwork><![CDATA[
wrap_client_id=music.example.com&wrap_client_secret=7F2986DF2342914A&w
rap_refresh_token=MfdWTc%2Bv9MXhpc%2Bd%2FcsrKFMPfj1RySm6CzIjmTBGN6w%3D
]]></artwork>
</figure>
<t>The Authorization Server looks up the data associated with the
Refresh Token, determines music.example.com is still authorized to
update Jane's status, and determines it will generate a new Access
Token for the Client that expires in an hour. The time is now
2010-01-02T04:15:23Z, which results in an Access Token expiry time of
1262438123 seconds since 1970-01-01T0:0:0Z. The Authorization Server
generates a new Access Token and returns it in the body of the message
as:</t>
<figure>
<artwork><![CDATA[
wrap_access_token=com.example.auth.scope=status_update&com.example.aut
h.account=Jane&com.example.auth.client=music.example.com&ExpiresOn=126
2438123&Audience=status.example.com&Issuer=auth.example.com&HMACSHA256
=AT4TFChHgyylItEWAjK7MFRJuvUS3WLVzO%2F68gvIRQI%3D&wrap_access_token_ex
pires_in=3600
]]></artwork>
</figure>
<t>The Client takes the new Access Token and uses it to successfully
update Jane's status at status.example.com.</t>
</section>
</section>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-23 02:49:25 |