mirror of
https://gitee.com/dcren/openiddict-documentation.git
synced 2025-07-15 23:13:34 +08:00
Add authorization storage documentation
This commit is contained in:
parent
ecc8a7ae8a
commit
2eb825416f
118
configuration/authorization-storage.md
Normal file
118
configuration/authorization-storage.md
Normal file
@ -0,0 +1,118 @@
|
||||
# Authorization storage
|
||||
|
||||
To keep track of logical chains of tokens and user consents, OpenIddict supports storing authorizations
|
||||
(also known as "grants" in some OpenID Connect implementations) in the database.
|
||||
|
||||
## Types of authorizations
|
||||
|
||||
Authorizations can be of two types: permanent and ad-hoc.
|
||||
|
||||
### Permanent authorizations
|
||||
|
||||
**Permanent authorizations are developer-defined authorizations** created using the `IOpenIddictAuthorizationManager.CreateAsync()` API
|
||||
and explicitly attached to a `ClaimsPrincipal` using the OpenIddict-specific `principal.SetAuthorizationId()` extension method.
|
||||
|
||||
Such authorizations are typically used to remember user consents and avoid displaying a consent view for each authorization request.
|
||||
For that, a "consent type" can be defined per-application, as in the following example:
|
||||
|
||||
```csharp
|
||||
// Retrieve the application details from the database.
|
||||
var application = await _applicationManager.FindByClientIdAsync(request.ClientId) ??
|
||||
throw new InvalidOperationException("The application cannot be found.");
|
||||
|
||||
// Retrieve the permanent authorizations associated with the user and the application.
|
||||
var authorizations = await _authorizationManager.FindAsync(
|
||||
subject: await _userManager.GetUserIdAsync(user),
|
||||
client : await _applicationManager.GetIdAsync(application),
|
||||
status : Statuses.Valid,
|
||||
type : AuthorizationTypes.Permanent,
|
||||
scopes : request.GetScopes()).ToListAsync();
|
||||
|
||||
switch (await _applicationManager.GetConsentTypeAsync(application))
|
||||
{
|
||||
// If the consent is external (e.g when authorizations are granted by a sysadmin),
|
||||
// immediately return an error if no authorization can be found in the database.
|
||||
case ConsentTypes.External when !authorizations.Any():
|
||||
return Forbid(
|
||||
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
|
||||
properties: new AuthenticationProperties(new Dictionary<string, string>
|
||||
{
|
||||
[OpenIddictServerAspNetCoreConstants.Properties.Error] =
|
||||
Errors.ConsentRequired,
|
||||
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] =
|
||||
"The logged in user is not allowed to access this client application."
|
||||
}));
|
||||
|
||||
// If the consent is implicit or if an authorization was found,
|
||||
// return an authorization response without displaying the consent form.
|
||||
case ConsentTypes.Implicit:
|
||||
case ConsentTypes.External when authorizations.Any():
|
||||
case ConsentTypes.Explicit when authorizations.Any() &&
|
||||
!request.HasPrompt(Prompts.Consent):
|
||||
var principal = await _signInManager.CreateUserPrincipalAsync(user);
|
||||
|
||||
// Note: in this sample, the granted scopes match the requested scope
|
||||
// but you may want to allow the user to uncheck specific scopes.
|
||||
// For that, simply restrict the list of scopes before calling SetScopes.
|
||||
principal.SetScopes(request.GetScopes());
|
||||
principal.SetResources(await _scopeManager.ListResourcesAsync(
|
||||
principal.GetScopes()).ToListAsync());
|
||||
|
||||
// Automatically create a permanent authorization to avoid requiring explicit consent
|
||||
// for future authorization or token requests containing the same scopes.
|
||||
var authorization = authorizations.LastOrDefault();
|
||||
if (authorization is null)
|
||||
{
|
||||
authorization = await _authorizationManager.CreateAsync(
|
||||
principal: principal,
|
||||
subject : await _userManager.GetUserIdAsync(user),
|
||||
client : await _applicationManager.GetIdAsync(application),
|
||||
type : AuthorizationTypes.Permanent,
|
||||
scopes : principal.GetScopes());
|
||||
}
|
||||
|
||||
principal.SetAuthorizationId(await _authorizationManager.GetIdAsync(authorization));
|
||||
|
||||
foreach (var claim in principal.Claims)
|
||||
{
|
||||
claim.SetDestinations(GetDestinations(claim, principal));
|
||||
}
|
||||
|
||||
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
|
||||
|
||||
// At this point, no authorization was found in the database and an error must be returned
|
||||
// if the client application specified prompt=none in the authorization request.
|
||||
case ConsentTypes.Explicit when request.HasPrompt(Prompts.None):
|
||||
case ConsentTypes.Systematic when request.HasPrompt(Prompts.None):
|
||||
return Forbid(
|
||||
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
|
||||
properties: new AuthenticationProperties(new Dictionary<string, string>
|
||||
{
|
||||
[OpenIddictServerAspNetCoreConstants.Properties.Error] =
|
||||
Errors.ConsentRequired,
|
||||
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] =
|
||||
"Interactive user consent is required."
|
||||
}));
|
||||
|
||||
// In every other case, render the consent form.
|
||||
default: return View(new AuthorizeViewModel
|
||||
{
|
||||
ApplicationName = await _applicationManager.GetLocalizedDisplayNameAsync(application),
|
||||
Scope = request.Scope
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Ad-hoc authorizations
|
||||
|
||||
**Ad-hoc authorizations are automatically created by OpenIddict when a chain of tokens needs to be tracked for security reasons**,
|
||||
but no explicit permanent authorization was attached by the developer to the `ClaimsPrincipal` used for the sign-in operation.
|
||||
|
||||
Such authorizations are typically created in the authorization code flow to link all the tokens associated with the original authorization code,
|
||||
so that they can be automatically revoked if the authorization code was redeemed multiple times (which may indicate a token leakage).
|
||||
In the same vein, ad-hoc authorizations are also created when a refresh token is returned during a resource owner password credentials grant request.
|
||||
|
||||
> [!INFO]
|
||||
> When using the [OpenIddict.Quartz](https://www.nuget.org/packages/OpenIddict.Quartz/) integration, ad-hoc authorizations are automatically
|
||||
> removed from the database after a short period of time (14 days by default). Unlike ad-hoc authorizations, permanent authorizations
|
||||
> never removed from the database.
|
@ -1,20 +1,3 @@
|
||||
# Configuration and settings
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-default" style="min-height: 120px;">
|
||||
<div class="panel-body">
|
||||
<p><strong><a href="application-permissions.md">Application permissions</a></strong></p>
|
||||
<p>Learn how to leverage permissions to control the OIDC features a client is allowed to use.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-default" style="min-height: 120px;">
|
||||
<div class="panel-body">
|
||||
<p><strong><a href="token-formats.md">Token formats</a></strong></p>
|
||||
<p>Learn more about the token formats supported by OpenIddict.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
OpenIddict 3.0 comes with sensible defaults, but depending on the scenarios, the default settings can be amended to change how OpenIddict reacts to requests.
|
@ -5,4 +5,7 @@
|
||||
href: application-permissions.md
|
||||
|
||||
- name: Token formats
|
||||
href: token-formats.md
|
||||
href: token-formats.md
|
||||
|
||||
- name: Authorization storage
|
||||
href: authorization-storage.md
|
Loading…
Reference in New Issue
Block a user