Update the documentation pages

This commit is contained in:
OpenIddict Bot
2023-04-29 15:54:59 +00:00
parent 8858ceeee4
commit 55127dcfe7
160 changed files with 5003 additions and 9196 deletions

View File

@@ -2,15 +2,15 @@
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Choosing the right flow </title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Choosing the right flow ">
<meta name="generator" content="docfx 2.56.7.0">
<meta name="generator" content="docfx ">
<link rel="shortcut icon" href="../images/favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/night-owl.min.css">
@@ -19,9 +19,9 @@
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body>
@@ -31,7 +31,7 @@
<svg name="Hamburger" style="vertical-align: middle;" width="24" height="24" viewbox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M20 6H4V9H20V6ZM4 10.999H20V13.999H4V10.999ZM4 15.999H20V18.999H4V15.999Z"></path></svg>
</a>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
@@ -46,25 +46,25 @@
<div class="sidebar">
<div>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
</a>
<div id="navbar">
</div>
</div>
<div class="sidebar-item-separator"></div>
<div id="sidetoggle">
<div id="sidetoc"></div>
</div>
@@ -72,8 +72,8 @@
</div>
<div class="footer">
<span>Generated by <strong>DocFX</strong></span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</nav>
@@ -81,7 +81,7 @@
<div role="main" class="hide-when-search">
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
@@ -101,21 +101,22 @@
<a href="https://tools.ietf.org/html/rfc6749#section-4.3">the resource owner password credentials grant</a> and
<a href="https://tools.ietf.org/html/rfc6749#section-4.4">the client credentials grant</a>.</p>
<p>While not specific to OpenIddict, choosing the best flow(s) for your application is an <strong>important prerequisite</strong>
when implementing your own authorization server ; so here&#39;s a quick overview of the different OAuth 2.0/OpenID Connect flows:</p>
when implementing your own authorization server ; so here's a quick overview of the different OAuth 2.0/OpenID Connect flows:</p>
<hr>
<h2 id="non-interactive-flows">Non-interactive flows</h2>
<h3 id="resource-owner-password-credentials-flow-not-recommended-for-new-applications">Resource owner password credentials flow (not recommended for new applications)</h3>
<p>Directly inspired by <a href="https://en.wikipedia.org/wiki/Basic_access_authentication">basic authentication</a>, the resource owner password credentials grant
(abbreviated <em>ROPC</em>) is conceptually <strong>the simplest OAuth 2.0 flow</strong>: the client application asks the user his username/password, sends a token request
to the authorization server with the user credentials (and depending on the client authentication policy defined by the authorization server,
its own client credentials) and gets back an access token it can use to retrieve the user&#39;s resources.</p>
its own client credentials) and gets back an access token it can use to retrieve the user's resources.</p>
<p><img src="choosing-the-right-flow/resource-owner-password-flow.png" alt="Resource owner password credentials flow"></p>
<pre><code class="lang-http">POST /connect/token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=password&amp;username=johndoe&amp;password=A3ddj3w
</code></pre><pre><code class="lang-http">HTTP/1.1 200 OK
</code></pre>
<pre><code class="lang-http">HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
@@ -125,16 +126,21 @@ Pragma: no-cache
&quot;token_type&quot;:&quot;bearer&quot;,
&quot;expires_in&quot;:3600
}
</code></pre><div class="CAUTION"><h5>Caution</h5><p>This flow is <strong>not recommended by the OAuth 2.0 specification</strong> as it&#39;s the only grant type where <strong>the user password is directly exposed to the client application</strong>,
which breaks the principle of least privilege and <strong>makes it unsuitable for third-party client applications that can&#39;t be fully trusted by the authorization server</strong>.</p>
<p>While popular and trivial to implement (as it doesn&#39;t involve any redirection or consent form and unlike interactive flows, doesn&#39;t require implementing
cross-site request forgery (XSRF) countermeasures to prevent session fixation attacks), <strong>its use in new applications is not recommended</strong>. Instead,
users are encouraged to use the authorization code flow, that doesn&#39;t expose passwords to client applications and is not limited to password authentication.</p>
</code></pre>
<div class="CAUTION">
<h5>Caution</h5>
<p>This flow is <strong>not recommended by the OAuth 2.0 specification</strong> as it's the only grant type where <strong>the user password is directly exposed to the client application</strong>,
which breaks the principle of least privilege and <strong>makes it unsuitable for third-party client applications that can't be fully trusted by the authorization server</strong>.</p>
</div>
<blockquote>
<p>While popular and trivial to implement (as it doesn't involve any redirection or consent form and unlike interactive flows, doesn't require implementing
cross-site request forgery (XSRF) countermeasures to prevent session fixation attacks), <strong>its use in new applications is not recommended</strong>. Instead,
users are encouraged to use the authorization code flow, that doesn't expose passwords to client applications and is not limited to password authentication.</p>
</blockquote>
<!-- more -->
<hr>
<h3 id="client-credentials-grant-recommended-for-machine-to-machine-communication">Client credentials grant (recommended for machine-to-machine communication)</h3>
<p>The client credentials grant is almost identical to the resource owner password credentials grant, except it&#39;s been specifically designed for <strong>client-to-server scenarios</strong>
<p>The client credentials grant is almost identical to the resource owner password credentials grant, except it's been specifically designed for <strong>client-to-server scenarios</strong>
(no user is involved in this flow): the client application sends a token request containing its credentials and gets back an access token it can use to query its own resources.</p>
<p><img src="choosing-the-right-flow/client-credentials-flow.png" alt="Client credentials flow"></p>
<pre><code class="lang-http">POST /connect/token HTTP/1.1
@@ -142,7 +148,8 @@ Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&amp;client_id=s6BhdRkqt3&amp;client_secret=gX1fBat3bV
</code></pre><pre><code class="lang-http">HTTP/1.1 200 OK
</code></pre>
<pre><code class="lang-http">HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
@@ -152,15 +159,18 @@ Pragma: no-cache
&quot;token_type&quot;:&quot;bearer&quot;,
&quot;expires_in&quot;:3600
}
</code></pre><div class="NOTE"><h5>Note</h5><p>Unlike the resource owner password credentials grant, <strong>client authentication is not optional</strong> when using the client credentials grant and
</code></pre>
<div class="NOTE">
<h5>Note</h5>
<p>Unlike the resource owner password credentials grant, <strong>client authentication is not optional</strong> when using the client credentials grant and
<strong>OpenIddict will always reject unauthenticated token requests</strong>, <a href="https://tools.ietf.org/html/rfc6749#section-4.4.2">as required by the OAuth 2.0 specification</a>.</p>
<p>This means that <strong>you CAN&#39;T use the client credentials grant with public applications</strong> like browser,
<p>This means that <strong>you CAN'T use the client credentials grant with public applications</strong> like browser,
mobile or desktop applications, as they are not able to keep their credentials secret.</p>
</div>
<hr>
<h2 id="interactive-flows">Interactive flows</h2>
<h3 id="authorization-code-flow-recommended-for-new-applications">Authorization code flow (recommended for new applications)</h3>
<p>While the authorization code flow is probably the most complicated flow (as it involves both <strong>user-agent redirections and backchannel communication</strong>), it&#39;s
<p>While the authorization code flow is probably the most complicated flow (as it involves both <strong>user-agent redirections and backchannel communication</strong>), it's
<strong>the recommended flow for any scenario involving end users, whether they log in using a password, a PIN, a smart card or even an external provider</strong>.
In return for its complexity, this flow has a great advantage when used in server-side applications: the <code>access_token</code> cannot be intercepted by the user agent.</p>
<p>There are basically 2 steps in the authorization code flow: the authorization request/response and the token request/response.</p>
@@ -171,30 +181,39 @@ In return for its complexity, this flow has a great advantage when used in serve
<p>In this flow, the client application always initiates the authentication process by generating an authorization request including
the mandatory <code>response_type=code</code> parameter, its <code>client_id</code>, its <code>redirect_uri</code> and optionally, a <code>scope</code> and a <code>state</code> parameter
<a href="https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest">that allows flowing custom data and helps mitigate XSRF attacks</a>.</p>
<div class="NOTE"><h5>Note</h5><p>In most cases, the client application will simply return a 302 response with a <code>Location</code> header to redirect the user agent to the authorization endpoint,
but depending on the OpenID Connect client you&#39;re using, POST requests might also be supported to allow you to send large authorization requests.
<div class="NOTE">
<h5>Note</h5>
<p>In most cases, the client application will simply return a 302 response with a <code>Location</code> header to redirect the user agent to the authorization endpoint,
but depending on the OpenID Connect client you're using, POST requests might also be supported to allow you to send large authorization requests.
This feature <a href="https://github.com/aspnet/Security/pull/392">is usually implemented using an auto-post HTML form</a>.</p>
</div>
<pre><code class="lang-http">HTTP/1.1 302 Found
Location: https://server.example.com/authorize?response_type=code&amp;client_id=s6BhdRkqt3&amp;state=af0ifjsldkj&amp;redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
</code></pre><pre><code class="lang-http">GET /connect/authorize?response_type=code&amp;client_id=s6BhdRkqt3&amp;state=af0ifjsldkj&amp;redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
</code></pre>
<pre><code class="lang-http">GET /connect/authorize?response_type=code&amp;client_id=s6BhdRkqt3&amp;state=af0ifjsldkj&amp;redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
Host: server.example.com
</code></pre><p>The way the identity provider handles the authorization request is implementation-specific but in most cases, a consent form
</code></pre>
<p>The way the identity provider handles the authorization request is implementation-specific but in most cases, a consent form
is displayed to ask the user if he or she agrees to share his/her personal data with the client application.</p>
<p><img src="choosing-the-right-flow/consent-form.png" alt="Consent form"></p>
<p>When the consent is given, the user agent is redirected back to the client application with <strong>a unique and short-lived token</strong>
named <em>authorization code</em> that the client will be able to exchange with an access token by sending a token request.</p>
<pre><code class="lang-http">HTTP/1.1 302 Found
Location: https://client.example.org/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=af0ifjsldkj
</code></pre><div class="WARNING"><h5>Warning</h5><p>To prevent XSRF/session fixation attacks, <strong>the client application MUST ensure that the <code>state</code> parameter returned by the identity provider
corresponds to the original <code>state</code></strong> and stop processing the authorization response if the two values don&#39;t match.
</code></pre>
<div class="WARNING">
<h5>Warning</h5>
<p>To prevent XSRF/session fixation attacks, <strong>the client application MUST ensure that the <code>state</code> parameter returned by the identity provider
corresponds to the original <code>state</code></strong> and stop processing the authorization response if the two values don't match.
<a href="https://tools.ietf.org/html/rfc6749#section-10.12">This is usually done by generating a non-guessable string and a corresponding correlation cookie</a>.</p>
</div>
<ul>
<li><strong>Step 2: the token request</strong></li>
</ul>
<p>When the client application gets back an authorization code, it must immediately reedem it for an access token by sending a <code>grant_type=authorization_code</code> token request.</p>
<div class="NOTE"><h5>Note</h5><p>To help the identity provider <a href="https://tools.ietf.org/html/rfc6819#section-4.4.1.7">mitigate counterfeit clients attacks</a>, the original <code>redirect_uri</code> must also be sent.</p>
<div class="NOTE">
<h5>Note</h5>
<p>To help the identity provider <a href="https://tools.ietf.org/html/rfc6819#section-4.4.1.7">mitigate counterfeit clients attacks</a>, the original <code>redirect_uri</code> must also be sent.</p>
<p>If the client application is a confidential application (i.e an application that has been assigned client credentials), authentication is required.</p>
</div>
<pre><code class="lang-http">POST /connect/token HTTP/1.1
@@ -202,7 +221,8 @@ Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&amp;code=SplxlOBeZQQYbYS6WxSbIA&amp;redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&amp;client_id=s6BhdRkqt3&amp;client_secret=gX1fBat3bV&amp;scope=openid
</code></pre><pre><code class="lang-http">HTTP/1.1 200 OK
</code></pre>
<pre><code class="lang-http">HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
@@ -212,24 +232,33 @@ Pragma: no-cache
&quot;token_type&quot;:&quot;bearer&quot;,
&quot;expires_in&quot;:3600
}
</code></pre><div class="NOTE"><h5>Note</h5><p>To increase security, additional parameters such as <code>code_challenge</code> and <code>code_challenge_method</code> can be specified to bind the authorization code
</code></pre>
<div class="NOTE">
<h5>Note</h5>
<p>To increase security, additional parameters such as <code>code_challenge</code> and <code>code_challenge_method</code> can be specified to bind the authorization code
that will be returned by the authorization endpoint to the original authorization request. This mechanism is known as
<a href="../configuration/proof-key-for-code-exchange.html">Proof Key for Code Exchange</a> and is fully supported by OpenIddict. </p>
<a href="../configuration/proof-key-for-code-exchange.html">Proof Key for Code Exchange</a> and is fully supported by OpenIddict.</p>
</div>
<hr>
<h3 id="implicit-flow-not-recommended-for-new-applications">Implicit flow (not recommended for new applications)</h3>
<p>The implicit flow is similar to the authorization code flow, <strong>except there&#39;s no token request/response step</strong>: the access token is directly returned
<p>The implicit flow is similar to the authorization code flow, <strong>except there's no token request/response step</strong>: the access token is directly returned
to the client application as part of the authorization response in the URI fragment (or in the request form when using <code>response_mode=form_post</code>).</p>
<p><img src="choosing-the-right-flow/implicit-flow.png" alt="Implicit flow"></p>
<pre><code class="lang-http">GET /connect/authorize?response_type=token&amp;client_id=s6BhdRkqt3&amp;redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb&amp;scope=openid&amp;state=af0ifjsldkj&amp;nonce=n-0S6_WzA2Mj HTTP/1.1
Host: server.example.com
</code></pre><pre><code class="lang-http">HTTP/1.1 302 Found
</code></pre>
<pre><code class="lang-http">HTTP/1.1 302 Found
Location: https://client.example.org/cb#access_token=SlAV32hkKG&amp;token_type=bearer&amp;expires_in=3600&amp;state=af0ifjsldkj
</code></pre><div class="CAUTION"><h5>Caution</h5><p>Initially designed for browser applications, this flow is inherently less secure than the authorization code flow and doesn&#39;t support
</code></pre>
<div class="CAUTION">
<h5>Caution</h5>
<p>Initially designed for browser applications, this flow is inherently less secure than the authorization code flow and doesn't support
<a href="https://tools.ietf.org/html/rfc7636">Proof Key for Code Exchange</a>. As such, using it in new applications is not recommended.</p>
</div>
<div class="WARNING"><h5>Warning</h5><p>To prevent XSRF/session fixation attacks, <strong>the client application MUST ensure that the <code>state</code> parameter returned by the identity provider
corresponds to the original <code>state</code></strong> and stop processing the authorization response if the two values don&#39;t match.
<div class="WARNING">
<h5>Warning</h5>
<p>To prevent XSRF/session fixation attacks, <strong>the client application MUST ensure that the <code>state</code> parameter returned by the identity provider
corresponds to the original <code>state</code></strong> and stop processing the authorization response if the two values don't match.
<a href="https://tools.ietf.org/html/rfc6749#section-10.12">This is usually done by generating a non-guessable string and a corresponding value stored in the local storage</a>.</p>
<p>When using the implicit flow, <strong>the client application MUST also ensure that the access token was not issued
to another application to prevent <a href="https://stackoverflow.com/a/17439317/542757">confused deputy attacks</a>.</strong>
@@ -242,16 +271,16 @@ of the JWT identity token, that must correspond or contain the <code>client_id</
</main>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>

View File

@@ -2,15 +2,15 @@
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Contributing a new Web provider </title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Contributing a new Web provider ">
<meta name="generator" content="docfx 2.56.7.0">
<meta name="generator" content="docfx ">
<link rel="shortcut icon" href="../images/favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/night-owl.min.css">
@@ -19,9 +19,9 @@
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body>
@@ -31,7 +31,7 @@
<svg name="Hamburger" style="vertical-align: middle;" width="24" height="24" viewbox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M20 6H4V9H20V6ZM4 10.999H20V13.999H4V10.999ZM4 15.999H20V18.999H4V15.999Z"></path></svg>
</a>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
@@ -46,25 +46,25 @@
<div class="sidebar">
<div>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
</a>
<div id="navbar">
</div>
</div>
<div class="sidebar-item-separator"></div>
<div id="sidetoggle">
<div id="sidetoc"></div>
</div>
@@ -72,8 +72,8 @@
</div>
<div class="footer">
<span>Generated by <strong>DocFX</strong></span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</nav>
@@ -81,7 +81,7 @@
<div role="main" class="hide-when-search">
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
@@ -110,7 +110,7 @@ and OWIN/ASP.NET 4.x applications, but also in Windows and Linux desktop applica
with the configuration needed to properly generate them. By eliminating all the plumbing code, the OpenIddict web providers are much easier to maintain and update.</p>
</li>
<li><p>To guarantee interoperability and make the best security choices, <strong>the OpenIddict client heavily relies on server configuration metadata</strong>, which differs from
the approach used by the ASP.NET Core OAuth 2.0 base handler, that doesn&#39;t support the OpenID Connect discovery and OAuth 2.0 authorization server metadata specifications.</p>
the approach used by the ASP.NET Core OAuth 2.0 base handler, that doesn't support the OpenID Connect discovery and OAuth 2.0 authorization server metadata specifications.</p>
</li>
</ul>
<p>Due to these differences, <strong>contributing a new provider to the OpenIddict stack is quite different from adding an aspnet-contrib provider</strong>:</p>
@@ -118,14 +118,17 @@ the approach used by the ASP.NET Core OAuth 2.0 base handler, that doesn&#39;t s
<p>To add a new OpenIddict web provider, <strong>the first step is to add a new <code>&lt;Provider&gt;</code> node</strong> to the <a href="https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml">OpenIddictClientWebIntegrationProviders.xml</a> file. For instance:</p>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Zendesk&quot; Documentation=&quot;https://developer.zendesk.com/documentation/live-chat/getting-started/auth/&quot;&gt;
&lt;/Provider&gt;
</code></pre><p>If available, a link to the official documentation MUST be added. If multiple languages are available, the following order SHOULD be used:</p>
</code></pre>
<p>If available, a link to the official documentation MUST be added. If multiple languages are available, the following order SHOULD be used:</p>
<ul>
<li>English</li>
<li>French</li>
<li>Spanish</li>
<li>Any other language</li>
</ul>
<div class="WARNING"><h5>Warning</h5><p>The added provider MUST be placed in the XML file such that the alphabetical order is respected.</p>
<div class="WARNING">
<h5>Warning</h5>
<p>The added provider MUST be placed in the XML file such that the alphabetical order is respected.</p>
</div>
<h2 id="add-an-environment-node-per-supported-environment">Add an <code>&lt;Environment&gt;</code> node per supported environment</h2>
<p><strong>The second step is to determine whether the service offers multiple environments</strong> (e.g Production, Testing or Development).</p>
@@ -137,18 +140,22 @@ the approach used by the ASP.NET Core OAuth 2.0 base handler, that doesn&#39;t s
&lt;Environment Name=&quot;Development&quot; /&gt;
&lt;/Provider&gt;
</code></pre><div class="WARNING"><h5>Warning</h5><p>When specifying multiple environments, the production environment MUST always appear first.</p>
</code></pre>
<div class="WARNING">
<h5>Warning</h5>
<p>When specifying multiple environments, the production environment MUST always appear first.</p>
</div>
<ul>
<li>If the provider doesn&#39;t support multiple environment, a single <code>&lt;Environment&gt;</code> MUST be added (the <code>Name</code> attribute SHOULD be omitted):</li>
<li>If the provider doesn't support multiple environment, a single <code>&lt;Environment&gt;</code> MUST be added (the <code>Name</code> attribute SHOULD be omitted):</li>
</ul>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Google&quot;&gt;
&lt;Environment /&gt;
&lt;/Provider&gt;
</code></pre><h2 id="add-the-appropriate-configuration-for-each-environment">Add the appropriate configuration for each environment</h2>
</code></pre>
<h2 id="add-the-appropriate-configuration-for-each-environment">Add the appropriate configuration for each environment</h2>
<p><strong>The third step is the most complicated one: adding the appropriate configuration for each of the added environments</strong>.</p>
<p>For that, you MUST first determine whether the environment supports OpenID Connect discovery or OAuth 2.0 authorization server metadata.
In some cases, this information will be mentioned in the official documentation, but it&#39;s not always true. By convention, the server metadata
In some cases, this information will be mentioned in the official documentation, but it's not always true. By convention, the server metadata
is typically served from <code>https://provider/.well-known/openid-configuration</code>: if you get a valid JSON document from this endpoint, the server
supports OpenID Connect/OAuth 2.0 server metadata.</p>
<ul>
@@ -159,8 +166,9 @@ so the correct issuer to use is <code>https://accounts.google.com/</code>:</li>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Google&quot;&gt;
&lt;Environment Issuer=&quot;https://accounts.google.com/&quot; /&gt;
&lt;/Provider&gt;
</code></pre><ul>
<li>If the server doesn&#39;t support OpenID Connect/OAuth 2.0 server metadata, you MUST add an <code>Issuer</code> attribute (corresponding to either
</code></pre>
<ul>
<li>If the server doesn't support OpenID Connect/OAuth 2.0 server metadata, you MUST add an <code>Issuer</code> attribute (corresponding to either
the value given in the documentation or the base address of the server) <strong>and</strong> a <code>&lt;Configuration&gt;</code> node with the static configuration needed by
the OpenIddict client to communicate with the remote authorization server. For instance:</li>
</ul>
@@ -174,7 +182,10 @@ the OpenIddict client to communicate with the remote authorization server. For i
&lt;/Configuration&gt;
&lt;/Environment&gt;
&lt;/Provider&gt;
</code></pre><div class="NOTE"><h5>Note</h5><p>If the provider doesn&#39;t support <code>grant_type=refresh_token</code> and only supports the authorization code flow
</code></pre>
<div class="NOTE">
<h5>Note</h5>
<p>If the provider doesn't support <code>grant_type=refresh_token</code> and only supports the authorization code flow
(typically with non-expiring access tokens), the <code>&lt;GrantType&gt;</code> nodes MUST be removed for clarity,
as the authorization code flow is always considered supported by default if no <code>&lt;GrantType&gt;</code> is present:</p>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Reddit&quot;&gt;
@@ -184,8 +195,11 @@ as the authorization code flow is always considered supported by default if no <
UserinfoEndpoint=&quot;https://oauth.reddit.com/api/v1/me&quot; /&gt;
&lt;/Environment&gt;
&lt;/Provider&gt;
</code></pre></div>
<div class="CAUTION"><h5>Caution</h5><p>If the provider doesn&#39;t support server metadata but is known to support Proof Key for Code Exchange (PKCE), a <code>&lt;CodeChallengeMethod&gt;</code> node MUST
</code></pre>
</div>
<div class="CAUTION">
<h5>Caution</h5>
<p>If the provider doesn't support server metadata but is known to support Proof Key for Code Exchange (PKCE), a <code>&lt;CodeChallengeMethod&gt;</code> node MUST
be added under <code>&lt;Configuration&gt;</code> to ensure the OpenIddict client will send appropriate <code>code_challenge</code>/<code>code_challenge_method</code> parameters:</p>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Fitbit&quot;&gt;
&lt;Environment Issuer=&quot;https://www.fitbit.com/&quot;&gt;
@@ -196,8 +210,11 @@ be added under <code>&lt;Configuration&gt;</code> to ensure the OpenIddict clien
&lt;/Configuration&gt;
&lt;/Environment&gt;
&lt;/Provider&gt;
</code></pre></div>
<div class="NOTE"><h5>Note</h5><p>Some providers use a multitenant configuration that relies on a subdomain, a custom domain or a virtual path to discriminate tenant instances.
</code></pre>
</div>
<div class="NOTE">
<h5>Note</h5>
<p>Some providers use a multitenant configuration that relies on a subdomain, a custom domain or a virtual path to discriminate tenant instances.
If the provider you want to support requires adding a dynamic part in one of its URIs, a <code>&lt;Setting&gt;</code> node MUST be added under <code>&lt;Provider&gt;</code> to
store the tenant name. Once added, the URIs can include a placeholder of the same name:</p>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Zendesk&quot;&gt;
@@ -216,7 +233,8 @@ store the tenant name. Once added, the URIs can include a placeholder of the sam
&lt;Setting PropertyName=&quot;Tenant&quot; ParameterName=&quot;tenant&quot; Type=&quot;String&quot; Required=&quot;true&quot;
Description=&quot;The tenant used to identify the Zendesk instance&quot; /&gt;
&lt;/Provider&gt;
</code></pre></div>
</code></pre>
</div>
<h2 id="test-the-generated-provider">Test the generated provider</h2>
<p>If the targeted service is fully standard-compliant, no additional configuration should be required at this point.
To confirm it, build the solution and add the new provider to the <code>OpenIddict.Sandbox.AspNetCore.Client</code> sandbox:</p>
@@ -232,7 +250,8 @@ options.UseWebProviders()
options.SetClientSecret(&quot;VcohOgBp-6yQCurngo4GAyKeZh0D6SUCCSjJgEo1uRzJarjIUS&quot;);
options.SetRedirectUri(&quot;callback/login/[provider name]&quot;);
});
</code></pre><ul>
</code></pre>
<ul>
<li>Update <code>AuthenticationController.cs</code> to allow triggering challenges pointing to the new provider:</li>
</ul>
<pre><code class="lang-csharp">// Note: OpenIddict always validates the specified provider name when handling the challenge operation,
@@ -243,21 +262,25 @@ if (!string.Equals(provider, &quot;Local&quot;, StringComparison.Ordinal) &amp;&
{
return BadRequest();
}
</code></pre><ul>
</code></pre>
<ul>
<li>Update <code>Index.cshtml</code> under <code>Views\Home</code> to include a login button for the new provider:</li>
</ul>
<pre><code class="lang-html">&lt;button class=&quot;btn btn-lg btn-success&quot; type=&quot;submit&quot; name=&quot;provider&quot; value=&quot;[provider name]&quot;&gt;
Sign in using [provider name]
&lt;/button&gt;
</code></pre><div class="NOTE"><h5>Note</h5><p>Unless you agree to share your sandbox credentials with the OpenIddict developers, the changes
made to the sandbox project don&#39;t need to be committed and included in your pull request.</p>
</code></pre>
<div class="NOTE">
<h5>Note</h5>
<p>Unless you agree to share your sandbox credentials with the OpenIddict developers, the changes
made to the sandbox project don't need to be committed and included in your pull request.</p>
</div>
<h2 id="if-necessary-add-the-necessary-workarounds-for-the-provider-to-work-correctly">If necessary, add the necessary workarounds for the provider to work correctly</h2>
<p>If an error occurs during the authentication process, the provider MAY require one or multiple workarounds for the integration to work correctly:</p>
<ul>
<li>The provider MAY require sending the client credentials as part of the <code>Authorization</code> header using basic authentication (i.e <code>client_secret_basic</code>).
Providers that implement OpenID Connect discovery or OAuth 2.0 authorization server metadata will typically return the client authentication methods they support.
If the provider doesn&#39;t expose its metadata, the supported methods MUST be added manually to the static configuration using one or multiple <code>&lt;TokenEndpointAuthMethod&gt;</code>:</li>
If the provider doesn't expose its metadata, the supported methods MUST be added manually to the static configuration using one or multiple <code>&lt;TokenEndpointAuthMethod&gt;</code>:</li>
</ul>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Twitter&quot;&gt;
&lt;Environment Issuer=&quot;https://twitter.com/&quot;&gt;
@@ -270,7 +293,8 @@ If the provider doesn&#39;t expose its metadata, the supported methods MUST be a
&lt;/Configuration&gt;
&lt;/Environment&gt;
&lt;/Provider&gt;
</code></pre><ul>
</code></pre>
<ul>
<li>The provider MAY require sending one or multiple default or required scopes. If so, the default/required scopes MUST be added to the <code>&lt;Environment&gt;</code> node:</li>
</ul>
<pre><code class="lang-xml">&lt;Provider Name=&quot;Twitter&quot; Documentation=&quot;https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code&quot;&gt;
@@ -293,9 +317,10 @@ If the provider doesn&#39;t expose its metadata, the supported methods MUST be a
&lt;Scope Name=&quot;users.read&quot; Default=&quot;true&quot; Required=&quot;true&quot; /&gt;
&lt;/Environment&gt;
&lt;/Provider&gt;
</code></pre><ul>
</code></pre>
<ul>
<li>The provider MAY require sending the scopes using a different separator than the standard one. While the OAuth 2.0 specification requires using a space
to separate multiple scopes, some providers require using a different separator (typically, a comma). If the provider you&#39;re adding requires such a hack,
to separate multiple scopes, some providers require using a different separator (typically, a comma). If the provider you're adding requires such a hack,
update the <code>FormatNonStandardScopeParameter</code> event handler present in
<a href="https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs">OpenIddictClientWebIntegrationHandlers.cs</a> to use the correct separator required by the provider.</li>
</ul>
@@ -336,12 +361,15 @@ public class FormatNonStandardScopeParameter : IOpenIddictClientHandler&lt;Proce
return default;
}
}
</code></pre><div class="NOTE"><h5>Note</h5><p>If the provider still doesn&#39;t work, it&#39;s unfortunately very likely more complex workarounds will be required.
If you&#39;re not familiar with the OpenIddict events model, open a ticket in the
</code></pre>
<div class="NOTE">
<h5>Note</h5>
<p>If the provider still doesn't work, it's unfortunately very likely more complex workarounds will be required.
If you're not familiar with the OpenIddict events model, open a ticket in the
<a href="https://github.com/openiddict/openiddict-core/issues"><code>openiddict-core</code></a> repository to get help.</p>
</div>
<h2 id="send-a-pull-request-against-the-openiddict-core-repository">Send a pull request against the <code>openiddict-core</code> repository</h2>
<p>Once you&#39;ve been able to confirm that your provider works correctly, all you need to do is send a PR so that it can be added to the
<p>Once you've been able to confirm that your provider works correctly, all you need to do is send a PR so that it can be added to the
<a href="https://github.com/openiddict/openiddict-core/issues"><code>openiddict-repo</code></a> and ship with the already supported providers as part of the next update.</p>
</article>
@@ -349,16 +377,16 @@ If you&#39;re not familiar with the OpenIddict events model, open a ticket in th
</main>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>

View File

@@ -2,15 +2,15 @@
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Getting started </title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Getting started ">
<meta name="generator" content="docfx 2.56.7.0">
<meta name="generator" content="docfx ">
<link rel="shortcut icon" href="../images/favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/night-owl.min.css">
@@ -19,9 +19,9 @@
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body>
@@ -31,7 +31,7 @@
<svg name="Hamburger" style="vertical-align: middle;" width="24" height="24" viewbox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M20 6H4V9H20V6ZM4 10.999H20V13.999H4V10.999ZM4 15.999H20V18.999H4V15.999Z"></path></svg>
</a>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
@@ -46,25 +46,25 @@
<div class="sidebar">
<div>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
</a>
<div id="navbar">
</div>
</div>
<div class="sidebar-item-separator"></div>
<div id="sidetoggle">
<div id="sidetoc"></div>
</div>
@@ -72,8 +72,8 @@
</div>
<div class="footer">
<span>Generated by <strong>DocFX</strong></span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</nav>
@@ -81,7 +81,7 @@
<div role="main" class="hide-when-search">
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
@@ -94,19 +94,20 @@
<h1 id="getting-started">Getting started</h1>
<p><strong>To implement a custom OpenID Connect server using OpenIddict, the simplest option is to clone one of the official samples</strong> from the <a href="https://github.com/openiddict/openiddict-samples">openiddict-samples repository</a>.</p>
<p>If you don&#39;t want to start from one of the recommended samples, you&#39;ll need to:</p>
<p>If you don't want to start from one of the recommended samples, you'll need to:</p>
<ul>
<li><p><strong>Install the <a href="https://www.microsoft.com/net/download">.NET Core 3.1 (or later) tooling</a></strong>.</p>
</li>
<li><p><strong>Have an existing project or create a new one</strong>: when creating a new project using Visual Studio&#39;s default ASP.NET Core template,
<li><p><strong>Have an existing project or create a new one</strong>: when creating a new project using Visual Studio's default ASP.NET Core template,
using <strong>individual user accounts authentication</strong> is strongly recommended as it automatically includes the default ASP.NET Core Identity UI, based on Razor Pages.</p>
</li>
<li><p><strong>Update your <code>.csproj</code> file</strong> to reference the latest <code>OpenIddict</code> packages:</p>
<pre><code class="lang-xml">&lt;PackageReference Include=&quot;OpenIddict.AspNetCore&quot; Version=&quot;4.2.0&quot; /&gt;
&lt;PackageReference Include=&quot;OpenIddict.EntityFrameworkCore&quot; Version=&quot;4.2.0&quot; /&gt;
</code></pre></li>
<pre><code class="lang-xml">&lt;PackageReference Include=&quot;OpenIddict.AspNetCore&quot; Version=&quot;4.3.0&quot; /&gt;
&lt;PackageReference Include=&quot;OpenIddict.EntityFrameworkCore&quot; Version=&quot;4.3.0&quot; /&gt;
</code></pre>
</li>
<li><p><strong>Configure the OpenIddict core, server and validation services</strong> in <code>Startup.ConfigureServices</code>.
Here&#39;s an example for the client credentials grant, used in machine-to-machine scenarios:</p>
Here's an example for the client credentials grant, used in machine-to-machine scenarios:</p>
<pre><code class="lang-csharp">public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
@@ -164,7 +165,8 @@ Here&#39;s an example for the client credentials grant, used in machine-to-machi
// Note: in a real world application, this step should be part of a setup script.
services.AddHostedService&lt;Worker&gt;();
}
</code></pre></li>
</code></pre>
</li>
<li><p><strong>Make sure the ASP.NET Core authentication middleware is correctly registered at the right place</strong>:</p>
<pre><code class="lang-csharp">public void Configure(IApplicationBuilder app)
{
@@ -181,7 +183,8 @@ Here&#39;s an example for the client credentials grant, used in machine-to-machi
options.MapDefaultControllerRoute();
});
}
</code></pre></li>
</code></pre>
</li>
<li><p><strong>Update your Entity Framework Core context registration to register the OpenIddict entities</strong>:</p>
<pre><code class="lang-csharp">services.AddDbContext&lt;ApplicationDbContext&gt;(options =&gt;
{
@@ -192,13 +195,16 @@ Here&#39;s an example for the client credentials grant, used in machine-to-machi
// Note: use the generic overload if you need to replace the default OpenIddict entities.
options.UseOpenIddict();
});
</code></pre><div class="NOTE"><h5>Note</h5><p>By default, the OpenIddict Entity Framework Core integration uses <code>string</code> as the default type for primary keys.
</code></pre>
<div class="NOTE">
<h5>Note</h5>
<p>By default, the OpenIddict Entity Framework Core integration uses <code>string</code> as the default type for primary keys.
To use a different type, read <a href="../integrations/entity-framework-core.html#use-a-custom-primary-key-type">Entity Framework Core integration : Use a custom primary key type</a>.</p>
</div>
</li>
<li><p><strong>Create your own authorization controller:</strong>
Implementing a custom authorization controller is required to allow OpenIddict to create tokens based on the identities and claims you provide.
Here&#39;s an example for the client credentials grant:</p>
Here's an example for the client credentials grant:</p>
<pre><code class="lang-csharp">public class AuthorizationController : Controller
{
private readonly IOpenIddictApplicationManager _applicationManager;
@@ -216,7 +222,7 @@ Here&#39;s an example for the client credentials grant:</p>
}
// Note: the client credentials are automatically validated by OpenIddict:
// if client_id or client_secret are invalid, this action won&#39;t be invoked.
// if client_id or client_secret are invalid, this action won't be invoked.
var application = await _applicationManager.FindByClientIdAsync(request.ClientId) ??
throw new InvalidOperationException(&quot;The application cannot be found.&quot;);
@@ -243,7 +249,8 @@ Here&#39;s an example for the client credentials grant:</p>
return SignIn(new ClaimsPrincipal(identity), OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
}
}
</code></pre></li>
</code></pre>
</li>
<li><p><strong>Register your client application</strong> (e.g from an <code>IHostedService</code> implementation):</p>
<pre><code class="lang-csharp">public class Worker : IHostedService
{
@@ -279,25 +286,27 @@ Here&#39;s an example for the client credentials grant:</p>
public Task StopAsync(CancellationToken cancellationToken) =&gt; Task.CompletedTask;
}
</code></pre><p>Before running the application, make sure the database is updated with OpenIddict tables by running <code>Add-Migration</code> and <code>Update-Database</code>.</p>
</code></pre>
</li>
</ul>
<p>Before running the application, make sure the database is updated with OpenIddict tables by running <code>Add-Migration</code> and <code>Update-Database</code>.</p>
</article>
</div>
</main>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>

View File

@@ -2,15 +2,15 @@
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>What's OpenIddict? </title>
<title>What&#39;s OpenIddict? </title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="What's OpenIddict? ">
<meta name="generator" content="docfx 2.56.7.0">
<meta name="title" content="What&#39;s OpenIddict? ">
<meta name="generator" content="docfx ">
<link rel="shortcut icon" href="../images/favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/night-owl.min.css">
@@ -19,9 +19,9 @@
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body>
@@ -31,7 +31,7 @@
<svg name="Hamburger" style="vertical-align: middle;" width="24" height="24" viewbox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M20 6H4V9H20V6ZM4 10.999H20V13.999H4V10.999ZM4 15.999H20V18.999H4V15.999Z"></path></svg>
</a>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
@@ -46,25 +46,25 @@
<div class="sidebar">
<div>
<a class="brand" href="../index.html">
<img src="../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
</a>
<div id="navbar">
</div>
</div>
<div class="sidebar-item-separator"></div>
<div id="sidetoggle">
<div id="sidetoc"></div>
</div>
@@ -72,8 +72,8 @@
</div>
<div class="footer">
<span>Generated by <strong>DocFX</strong></span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</nav>
@@ -81,7 +81,7 @@
<div role="main" class="hide-when-search">
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
@@ -91,7 +91,7 @@
</div>
<article class="content wrap" id="_content" data-uid="">
<h2 id="whats-openiddict">What&#39;s OpenIddict?</h2>
<h2 id="whats-openiddict">What's OpenIddict?</h2>
<p>OpenIddict is <strong>an open source and versatile framework for building standard-compliant OAuth 2.0/OpenID Connect servers</strong>
in any ASP.NET Core 2.1 (and higher) and legacy ASP.NET 4.6.1 (and higher) applications.</p>
@@ -137,7 +137,8 @@ OpenIddict will automatically reject the request before it reaches user-defined
options.UseAspNetCore()
.EnableAuthorizationEndpointPassthrough();
});
</code></pre><pre><code class="lang-csharp">app.MapGet(&quot;/authorize&quot;, async (HttpContext context) =&gt;
</code></pre>
<pre><code class="lang-csharp">app.MapGet(&quot;/authorize&quot;, async (HttpContext context) =&gt;
{
// Resolve the claims stored in the principal created after the Steam authentication dance.
// If the principal cannot be found, trigger a new challenge to redirect the user to Steam.
@@ -156,11 +157,12 @@ OpenIddict will automatically reject the request before it reaches user-defined
return Results.SignIn(new ClaimsPrincipal(identity), properties: null, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
});
</code></pre><h3 id="events-model">Events model</h3>
</code></pre>
<h3 id="events-model">Events model</h3>
<p>OpenIddict implements a powerful event-based model for its server and validation stacks: each part of the request processing logic is implemented as an event handler
that can be removed, moved to a different position in the pipeline or replaced by a custom handler to override the default logic used by OpenIddict:</p>
<pre><code class="lang-csharp">/// &lt;summary&gt;
/// Contains the logic responsible of rejecting authorization requests that don&#39;t specify a valid prompt parameter.
/// Contains the logic responsible of rejecting authorization requests that don't specify a valid prompt parameter.
/// &lt;/summary&gt;
public class ValidatePromptParameter : IOpenIddictServerHandler&lt;ValidateAuthorizationRequestContext&gt;
{
@@ -200,7 +202,8 @@ public class ValidatePromptParameter : IOpenIddictServerHandler&lt;ValidateAutho
return default;
}
}
</code></pre><p>In OpenIddict itself, event handlers are typically defined as dedicated classes but they can also be registered using delegates:</p>
</code></pre>
<p>In OpenIddict itself, event handlers are typically defined as dedicated classes but they can also be registered using delegates:</p>
<pre><code class="lang-csharp">services.AddOpenIddict()
.AddServer(options =&gt;
{
@@ -213,22 +216,23 @@ public class ValidatePromptParameter : IOpenIddictServerHandler&lt;ValidateAutho
return default;
}));
});
</code></pre></article>
</code></pre>
</article>
</div>
</main>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>

View File

@@ -2,15 +2,15 @@
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Migrate to OpenIddict 3.0 </title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Migrate to OpenIddict 3.0 ">
<meta name="generator" content="docfx 2.56.7.0">
<meta name="generator" content="docfx ">
<link rel="shortcut icon" href="../../images/favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/night-owl.min.css">
@@ -19,9 +19,9 @@
<link rel="stylesheet" href="../../styles/main.css">
<meta property="docfx:navrel" content="../../toc.html">
<meta property="docfx:tocrel" content="../toc.html">
</head>
<body>
@@ -31,7 +31,7 @@
<svg name="Hamburger" style="vertical-align: middle;" width="24" height="24" viewbox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M20 6H4V9H20V6ZM4 10.999H20V13.999H4V10.999ZM4 15.999H20V18.999H4V15.999Z"></path></svg>
</a>
<a class="brand" href="../../index.html">
<img src="../../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
@@ -46,25 +46,25 @@
<div class="sidebar">
<div>
<a class="brand" href="../../index.html">
<img src="../../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
</a>
<div id="navbar">
</div>
</div>
<div class="sidebar-item-separator"></div>
<div id="sidetoggle">
<div id="sidetoc"></div>
</div>
@@ -72,8 +72,8 @@
</div>
<div class="footer">
<span>Generated by <strong>DocFX</strong></span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</nav>
@@ -81,7 +81,7 @@
<div role="main" class="hide-when-search">
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
@@ -93,9 +93,11 @@
<article class="content wrap" id="_content" data-uid="">
<h1 id="migrate-to-openiddict-30">Migrate to OpenIddict 3.0</h1>
<h2 id="whats-new">What&#39;s new?</h2>
<h2 id="whats-new">What's new?</h2>
<p>The announcement listing the changes introduced in this milestone can be found <a href="https://kevinchalet.com/2020/12/23/openiddict-3-0-general-availability/">here</a>.</p>
<div class="IMPORTANT"><h5>Important</h5><p><strong>Migrating to OpenIddict 3.0 requires making changes to your database</strong>: existing properties have been reworked and new ones have been added to support the new features.</p>
<div class="IMPORTANT">
<h5>Important</h5>
<p><strong>Migrating to OpenIddict 3.0 requires making changes to your database</strong>: existing properties have been reworked and new ones have been added to support the new features.</p>
</div>
<h2 id="update-your-packages-references">Update your packages references</h2>
<p>For that, update your <code>.csproj</code> file to reference the <code>OpenIddict.AspNetCore</code> 3.x metapackage:</p>
@@ -103,9 +105,10 @@
&lt;PackageReference Include=&quot;OpenIddict.AspNetCore&quot; Version=&quot;3.1.1&quot; /&gt;
&lt;PackageReference Include=&quot;OpenIddict.EntityFrameworkCore&quot; Version=&quot;3.1.1&quot; /&gt;
&lt;/ItemGroup&gt;
</code></pre><h2 id="ensure-your-application-doesnt-reference-legacyunsupported-packages">Ensure your application doesn&#39;t reference legacy/unsupported packages</h2>
</code></pre>
<h2 id="ensure-your-application-doesnt-reference-legacyunsupported-packages">Ensure your application doesn't reference legacy/unsupported packages</h2>
<p>As part of the AspNet.Security.OpenIdConnect.Server/OpenIddict merge, the ASOS packages and 2 OpenIddict packages have been marked as legacy
and are no longer supported. Make sure your application (or intermediate libraries) don&#39;t reference any of these packages:</p>
and are no longer supported. Make sure your application (or intermediate libraries) don't reference any of these packages:</p>
<table>
<thead>
<tr>
@@ -160,7 +163,9 @@ and are no longer supported. Make sure your application (or intermediate librari
</tr>
</tbody>
</table>
<div class="IMPORTANT"><h5>Important</h5><p>If your application references the <code>OpenIdConnectConstants</code> class, update it to use <code>OpenIddictConstants</code> instead.</p>
<div class="IMPORTANT">
<h5>Important</h5>
<p>If your application references the <code>OpenIdConnectConstants</code> class, update it to use <code>OpenIddictConstants</code> instead.</p>
</div>
<h2 id="update-the-references-to-the-entity-framework-coreentity-framework-6mongodb-models">Update the references to the Entity Framework Core/Entity Framework 6/MongoDB models</h2>
<p>If your application references the <code>OpenIddictApplication</code>, <code>OpenIddictAuthorization</code>, <code>OpenIddictScope</code> or <code>OpenIddictToken</code> models,
@@ -212,8 +217,9 @@ update these reference to use their new names:</p>
{
options.UseAspNetCore();
});
</code></pre><h2 id="enable-the-authorization-logout-and-token-endpoints-pass-through-mode">Enable the authorization, logout and token endpoints pass-through mode</h2>
<p>Unless you&#39;re using OpenIddict&#39;s events model to handle authorization, logout and token requests, you&#39;ll need to enable
</code></pre>
<h2 id="enable-the-authorization-logout-and-token-endpoints-pass-through-mode">Enable the authorization, logout and token endpoints pass-through mode</h2>
<p>Unless you're using OpenIddict's events model to handle authorization, logout and token requests, you'll need to enable
the pass-through mode for these endpoints, so that requests can reach your authorization controller as in the previous versions:</p>
<pre><code class="lang-csharp">services.AddOpenIddict()
.AddServer(options =&gt;
@@ -223,7 +229,8 @@ the pass-through mode for these endpoints, so that requests can reach your autho
.EnableLogoutEndpointPassthrough()
.EnableTokenEndpointPassthrough();
});
</code></pre><h2 id="enable-aspnet-core-data-protection-support-to-ensure-existing-tokens-can-still-be-validated">Enable ASP.NET Core Data Protection support to ensure existing tokens can still be validated</h2>
</code></pre>
<h2 id="enable-aspnet-core-data-protection-support-to-ensure-existing-tokens-can-still-be-validated">Enable ASP.NET Core Data Protection support to ensure existing tokens can still be validated</h2>
<p>For that, call <code>options.UseDataProtection()</code> in both the server and validation options:</p>
<pre><code class="lang-csharp">services.AddOpenIddict()
.AddServer(options =&gt;
@@ -234,9 +241,10 @@ the pass-through mode for these endpoints, so that requests can reach your autho
{
options.UseDataProtection();
});
</code></pre><h2 id="use-the-new-request-caching-apis-if-applicable">Use the new request caching APIs, if applicable</h2>
</code></pre>
<h2 id="use-the-new-request-caching-apis-if-applicable">Use the new request caching APIs, if applicable</h2>
<p>In 3.0, the <code>OpenIddictServerBuilder.EnableRequestCaching()</code> API - that enabled request caching for both authorization and logout request -
was replaced by 2 separate methods. If your application depends on request caching, don&#39;t forget to enable it when migrating to 3.0:</p>
was replaced by 2 separate methods. If your application depends on request caching, don't forget to enable it when migrating to 3.0:</p>
<pre><code class="lang-csharp">services.AddOpenIddict()
.AddServer(options =&gt;
{
@@ -244,7 +252,8 @@ was replaced by 2 separate methods. If your application depends on request cachi
.EnableAuthorizationRequestCaching()
.EnableLogoutRequestCaching();
});
</code></pre><h2 id="replace-jsonnet-by-systemtextjson">Replace JSON.NET by <code>System.Text.Json</code></h2>
</code></pre>
<h2 id="replace-jsonnet-by-systemtextjson">Replace JSON.NET by <code>System.Text.Json</code></h2>
<p>If you use JSON.NET to serialize or deserialize <code>OpenIdConnectMessage</code>, <code>OpenIdConnectRequest</code> or <code>OpenIdConnectResponse</code> instances,
consider moving to <code>System.Text.Json</code> when migrating to OpenIddict 3.0, as 3.0 no longer includes a built-in JSON.NET <code>JsonConverter</code> for their
equivalent in 3.0 (i.e <code>OpenIddictMessage</code>, <code>OpenIddictRequest</code> and <code>OpenIddictResponse</code>).</p>
@@ -277,7 +286,9 @@ If you have calls like <code>ticket.SetScopes()</code> or <code>ticket.SetResour
</tr>
</tbody>
</table>
<div class="NOTE"><h5>Note</h5><p>In 3.0, the OpenIddict server ASP.NET Core handler supports authenticating userinfo requests. As such, if you use the pass-through mode
<div class="NOTE">
<h5>Note</h5>
<p>In 3.0, the OpenIddict server ASP.NET Core handler supports authenticating userinfo requests. As such, if you use the pass-through mode
to handle userinfo requests in your own userinfo MVC action, consider using <code>OpenIddictServerAspNetCoreDefaults.AuthenticationScheme</code>
instead of <code>OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme</code> for your userinfo endpoint to avoid validating access tokens twice.</p>
</div>
@@ -293,7 +304,8 @@ still work after migrating, consider using the <code>principal.HasScope()</code>
builder.RequireAssertion(context =&gt; context.User.HasScope(&quot;api1&quot;));
});
});
</code></pre><p>Alternatively, you can use the check the presence of the private OpenIddict <code>oi_scp</code> claims that use the same format as in 2.x (i.e one claim per scope value):</p>
</code></pre>
<p>Alternatively, you can use the check the presence of the private OpenIddict <code>oi_scp</code> claims that use the same format as in 2.x (i.e one claim per scope value):</p>
<pre><code class="lang-csharp">services.AddAuthorization(options =&gt;
{
options.AddPolicy(&quot;MyPolicy&quot;, builder =&gt;
@@ -302,8 +314,11 @@ still work after migrating, consider using the <code>principal.HasScope()</code>
builder.RequireClaim(Claims.Private.Scope, &quot;api1&quot;);
});
});
</code></pre><div class="CAUTION"><h5>Caution</h5><p>These 2 options only work with the OpenIddict validation handler as the <code>oi_scp</code> claims are not populated by the JWT bearer handler developped by Microsoft.
If you can&#39;t migrate to the OpenIddict validation handler, consider splitting the standard <code>scope</code> claim manually to determine whether it contains a specific value.</p>
</code></pre>
<div class="CAUTION">
<h5>Caution</h5>
<p>These 2 options only work with the OpenIddict validation handler as the <code>oi_scp</code> claims are not populated by the JWT bearer handler developped by Microsoft.
If you can't migrate to the OpenIddict validation handler, consider splitting the standard <code>scope</code> claim manually to determine whether it contains a specific value.</p>
</div>
<h2 id="add-and-apply-migrations-if-necessary">Add and apply migrations, if necessary</h2>
<p>If your application uses Entity Framework Core or Entity Framework 6, add a migration to react to the schema changes listed below and apply it.</p>
@@ -396,9 +411,12 @@ and the hybrid flow MUST be explicitly opted in. If you use the hybrid flow, mak
{
options.AllowHybridFlow();
});
</code></pre><h2 id="update-your-applications-to-grant-them-the-appropriate-response-type-permissions">Update your applications to grant them the appropriate response type permissions</h2>
</code></pre>
<h2 id="update-your-applications-to-grant-them-the-appropriate-response-type-permissions">Update your applications to grant them the appropriate response type permissions</h2>
<p>New response type permissions - enforced by default - <a href="/configuration/application-permissions.html#response-type-permissions">have been introduced in 3.0</a>.</p>
<div class="NOTE"><h5>Note</h5><p>If you have many applications to migrate, you can use <a href="https://github.com/openiddict/openiddict-core/issues/1138#issuecomment-713681158">this script</a>
<div class="NOTE">
<h5>Note</h5>
<p>If you have many applications to migrate, you can use <a href="https://github.com/openiddict/openiddict-core/issues/1138#issuecomment-713681158">this script</a>
to infer appropriate response type permissions using the already granted grant types.</p>
</div>
</article>
@@ -407,16 +425,16 @@ to infer appropriate response type permissions using the already granted grant t
</main>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../../styles/docfx.js"></script>
<script type="text/javascript" src="../../styles/main.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../../styles/docfx.js"></script>
<script type="text/javascript" src="../../styles/main.js"></script>
</body>

View File

@@ -2,15 +2,15 @@
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Migrate to OpenIddict 4.0 </title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Migrate to OpenIddict 4.0 ">
<meta name="generator" content="docfx 2.56.7.0">
<meta name="generator" content="docfx ">
<link rel="shortcut icon" href="../../images/favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/night-owl.min.css">
@@ -19,9 +19,9 @@
<link rel="stylesheet" href="../../styles/main.css">
<meta property="docfx:navrel" content="../../toc.html">
<meta property="docfx:tocrel" content="../toc.html">
</head>
<body>
@@ -31,7 +31,7 @@
<svg name="Hamburger" style="vertical-align: middle;" width="24" height="24" viewbox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M20 6H4V9H20V6ZM4 10.999H20V13.999H4V10.999ZM4 15.999H20V18.999H4V15.999Z"></path></svg>
</a>
<a class="brand" href="../../index.html">
<img src="../../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
@@ -46,25 +46,25 @@
<div class="sidebar">
<div>
<a class="brand" href="../../index.html">
<img src="../../images/logo.png" alt="OpenIddict" class="logomark">
<span class="brand-title">OpenIddict</span>
</a>
<div id="navbar">
</div>
</div>
<div class="sidebar-item-separator"></div>
<div id="sidetoggle">
<div id="sidetoc"></div>
</div>
@@ -72,8 +72,8 @@
</div>
<div class="footer">
<span>Generated by <strong>DocFX</strong></span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</nav>
@@ -81,7 +81,7 @@
<div role="main" class="hide-when-search">
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
@@ -93,9 +93,11 @@
<article class="content wrap" id="_content" data-uid="">
<h1 id="migrate-to-openiddict-40">Migrate to OpenIddict 4.0</h1>
<h2 id="whats-new">What&#39;s new?</h2>
<h2 id="whats-new">What's new?</h2>
<p>The most important changes introduced in 4.0 can be found <a href="https://github.com/openiddict/openiddict-core/releases">here</a>.</p>
<div class="NOTE"><h5>Note</h5><p><strong>Unless you&#39;re using MongoDB, migrating to OpenIddict 4.0 doesn&#39;t require making changes to your database</strong>.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Unless you're using MongoDB, migrating to OpenIddict 4.0 doesn't require making changes to your database</strong>.</p>
</div>
<h2 id="update-your-packages-references">Update your packages references</h2>
<p>For that, update your <code>.csproj</code> file to reference the <code>OpenIddict</code> 4.x packages. For instance:</p>
@@ -108,7 +110,10 @@
&lt;PackageReference Include=&quot;OpenIddict.AspNetCore&quot; Version=&quot;4.0.0&quot; /&gt;
&lt;PackageReference Include=&quot;OpenIddict.EntityFrameworkCore&quot; Version=&quot;4.0.0&quot; /&gt;
&lt;/ItemGroup&gt;
</code></pre><div class="NOTE"><h5>Note</h5><p>Migrating to ASP.NET Core 7.0 is not required, as OpenIddict 4.0 is still natively compatible with ASP.NET Core 2.1 (.NET Framework-only),
</code></pre>
<div class="NOTE">
<h5>Note</h5>
<p>Migrating to ASP.NET Core 7.0 is not required, as OpenIddict 4.0 is still natively compatible with ASP.NET Core 2.1 (.NET Framework-only),
ASP.NET Core 3.1 and ASP.NET Core 6.0. Moving to a newer .NET runtime or ASP.NET Core can be done separately for a simpler/decoupled upgrade:</p>
<table>
<thead>
@@ -194,7 +199,8 @@ read <a href="https://github.com/openiddict/openiddict-core/issues/1613">Breakin
.SetUserinfoEndpointUris(&quot;connect/userinfo&quot;)
.SetVerificationEndpointUris(&quot;connect/verify&quot;);
});
</code></pre><h2 id="remove-calls-to-addclaims-that-specify-a-list-of-destinations">Remove calls to <code>AddClaim(s)</code> that specify a list of destinations:</h2>
</code></pre>
<h2 id="remove-calls-to-addclaims-that-specify-a-list-of-destinations">Remove calls to <code>AddClaim(s)</code> that specify a list of destinations:</h2>
<p>As explained in <a href="https://kevinchalet.com/2022/06/22/openiddict-4-0-preview1-is-out/">OpenIddict 4.0 preview1 is out</a>,
the <code>AddClaim(s)</code> extensions that accepted a <code>destinations</code> parameter have been removed in 4.0.</p>
<p>Instead, developers are encouraged to use the new one-shot <code>SetDestinations()</code> extension for <code>ClaimsIdentity</code>
@@ -222,7 +228,8 @@ identity.SetDestinations(static claim =&gt; claim.Type switch
// Otherwise, only store the claim in the access tokens.
_ =&gt; new[] { Destinations.AccessToken }
});
</code></pre><h2 id="if-applicable-update-your-openiddict-mongodb-authorizations">If applicable, update your OpenIddict MongoDB authorizations</h2>
</code></pre>
<h2 id="if-applicable-update-your-openiddict-mongodb-authorizations">If applicable, update your OpenIddict MongoDB authorizations</h2>
<p>To match the casing used by the other properties, the name used in the BSON representation of the <code>OpenIddictMongoDbAuthorization.CreationDate</code>
property was fixed to use camel case (i.e <code>creation_name</code> instead of <code>CreationDate</code>). To ensure the existing authorizations are correctly
updated to use the new name, the following script can be used to update all the existing authorizations at once very efficiently:</p>
@@ -247,7 +254,8 @@ var authorizations = database.GetCollection&lt;BsonDocument&gt;(options.Authoriz
await authorizations.UpdateManyAsync(
filter: Builders&lt;BsonDocument&gt;.Filter.Empty,
update: Builders&lt;BsonDocument&gt;.Update.Rename(&quot;CreationDate&quot;, &quot;creation_date&quot;));
</code></pre><h2 id="if-applicable-replace-references-to-portablebouncycastle-by-bouncycastlecryptography">If applicable, replace references to <code>Portable.BouncyCastle</code> by <code>BouncyCastle.Cryptography</code></h2>
</code></pre>
<h2 id="if-applicable-replace-references-to-portablebouncycastle-by-bouncycastlecryptography">If applicable, replace references to <code>Portable.BouncyCastle</code> by <code>BouncyCastle.Cryptography</code></h2>
<p>While previous versions of OpenIddict used the unofficial <a href="https://www.nuget.org/packages/Portable.BouncyCastle"><code>Portable.BouncyCastle</code></a>
package maintained by <a href="https://github.com/clairernovotny">Claire Novotny</a> (which was the best .NET Standard-compatible option at the time),
OpenIddict 4.0 was updated to use the official package, <a href="https://www.nuget.org/packages/BouncyCastle.Cryptography">BouncyCastle.Cryptography</a>,
@@ -266,7 +274,8 @@ ValueTask&lt;TResult&gt; GetAsync&lt;TState, TResult&gt;(
ValueTask&lt;TResult?&gt; GetAsync&lt;TState, TResult&gt;(
Func&lt;IQueryable&lt;TApplication&gt;, TState, IQueryable&lt;TResult&gt;&gt; query,
TState state, CancellationToken cancellationToken);
</code></pre><p>While not required, it is recommended to also update implementations of <code>IOpenIddictApplicationStore</code> to use the updated parameter names
</code></pre>
<p>While not required, it is recommended to also update implementations of <code>IOpenIddictApplicationStore</code> to use the updated parameter names
for <code>FindByPostLogoutRedirectUriAsync()</code>, <code>FindByRedirectUriAsync()</code>, <code>SetPostLogoutRedirectUrisAsync()</code> and <code>SetRedirectUrisAsync()</code>:</p>
<pre><code class="lang-csharp">// OpenIddict 3.x:
IAsyncEnumerable&lt;TApplication&gt; FindByPostLogoutRedirectUriAsync(string address, CancellationToken cancellationToken);
@@ -279,7 +288,8 @@ IAsyncEnumerable&lt;TApplication&gt; FindByPostLogoutRedirectUriAsync(string uri
IAsyncEnumerable&lt;TApplication&gt; FindByRedirectUriAsync(string uri, CancellationToken cancellationToken);
ValueTask SetPostLogoutRedirectUrisAsync(TApplication application, ImmutableArray&lt;string&gt; uris, CancellationToken cancellationToken);
ValueTask SetRedirectUrisAsync(TApplication application, ImmutableArray&lt;string&gt; uris, CancellationToken cancellationToken);
</code></pre><h2 id="consider-migrating-to-the-new-openiddict-client-optional">Consider migrating to the new OpenIddict client (optional)</h2>
</code></pre>
<h2 id="consider-migrating-to-the-new-openiddict-client-optional">Consider migrating to the new OpenIddict client (optional)</h2>
<p>OpenIddict 4.0 introduces a new client stack that is natively compatible with all supported versions of ASP.NET Core (2.1
on .NET Framework, 3.1, 6.0 and 7.0) and <code>Microsoft.Owin</code> 4.2 (which means it can also be used on ASP.NET 4.6.1 and higher).</p>
<p>For more information, read <a href="https://kevinchalet.com/2022/12/23/openiddict-4-0-general-availability/">OpenIddict 4.0 general availability</a>.</p>
@@ -289,16 +299,16 @@ on .NET Framework, 3.1, 6.0 and 7.0) and <code>Microsoft.Owin</code> 4.2 (which
</main>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../../styles/docfx.js"></script>
<script type="text/javascript" src="../../styles/main.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
<script type="text/javascript" src="../../styles/jquery.twbsPagination.js"></script>
<script type="text/javascript" src="../../styles/url.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script type="text/javascript" src="../../styles/docfx.js"></script>
<script type="text/javascript" src="../../styles/main.js"></script>
</body>

View File

@@ -3,53 +3,53 @@
<div>
<div class="sidetoc">
<div class="toc" id="toc">
<ul class="nav level1">
<li>
<a href="index.html" class="sidebar-item" name="" title="Introduction">Introduction</a>
</li>
<li>
<a href="contributing-a-new-web-provider.html" class="sidebar-item" name="" title="Contributing a new Web provider">Contributing a new Web provider</a>
</li>
<li>
<a href="getting-started.html" class="sidebar-item" name="" title="Getting started">Getting started</a>
</li>
<li>
<a href="choosing-the-right-flow.html" class="sidebar-item" name="" title="Choosing the right flow">Choosing the right flow</a>
</li>
<li>
<span class="expand-stub"></span>
<a class="sidebar-item" name="" title="Migration guides">Migration guides</a>
<ul class="nav level2">
<li>
<a href="migration/20-to-30.html" class="sidebar-item" name="" title="Migration from 2.0 to 3.0">Migration from 2.0 to 3.0</a>
</li>
<li>
<a href="migration/30-to-40.html" class="sidebar-item" name="" title="Migration from 3.0 to 4.0">Migration from 3.0 to 4.0</a>
</li>
</ul>
</li>
<li>
<span class="expand-stub"></span>
<a class="sidebar-item" name="" title="External resources">External resources</a>
<ul class="nav level2">
<li>
<a href="https://tools.ietf.org/html/rfc6749" class="sidebar-item" name="" title="OAuth 2.0 specification">OAuth 2.0 specification</a>
</li>
<li>
<a href="https://openid.net/specs/openid-connect-core-1_0.html" class="sidebar-item" name="" title="OpenID Connect specification">OpenID Connect specification</a>
</li>
</ul>
</li>