diff --git a/guides/getting-started.md b/guides/getting-started.md index 2519ab2..49fe948 100644 --- a/guides/getting-started.md +++ b/guides/getting-started.md @@ -157,8 +157,7 @@ If you don't want to start from one of the recommended samples, you'll need to: await _applicationManager.GetDisplayNameAsync(application), Destinations.AccessToken, Destinations.IdentityToken); - return SignIn(new ClaimsPrincipal(identity), - OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); + return SignIn(new ClaimsPrincipal(identity), OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); } } ``` @@ -180,8 +179,7 @@ If you don't want to start from one of the recommended samples, you'll need to: var context = scope.ServiceProvider.GetRequiredService(); await context.Database.EnsureCreatedAsync(); - var manager = - scope.ServiceProvider.GetRequiredService(); + var manager = scope.ServiceProvider.GetRequiredService(); if (await manager.FindByClientIdAsync("console") is null) { diff --git a/guides/index.md b/guides/index.md index d3badff..58f969a 100644 --- a/guides/index.md +++ b/guides/index.md @@ -1,13 +1,146 @@ -# Introduction - ## What's OpenIddict? -OpenIddict was born in late 2015 and was initially based on **[AspNet.Security.OpenIdConnect.Server](https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server)** -(codenamed ASOS), a low-level OpenID Connect server middleware forked from OWIN/Katana's `OAuthAuthorizationServerMiddleware`. In 2020, ASOS was merged into OpenIddict 3.0 -to form a unified stack under the OpenIddict umbrella, while still offering an easy-to-use approach for new users and a low-level experience for advanced users. +OpenIddict is **an open source and versatile framework for building standard-compliant OAuth 2.0/OpenID Connect servers** +in any ASP.NET Core 2.1 (and higher) and legacy ASP.NET 4.6.1 (and higher) applications. -## Why an OpenID Connect server? +OpenIddict was born in late 2015 and was initially based on [AspNet.Security.OpenIdConnect.Server](https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server) +(codenamed ASOS), a low-level OpenID Connect server middleware inspired by the OAuth 2.0 authorization server middleware developed by Microsoft for the OWIN project +and the first OpenID Connect server ever created for ASP.NET Core. -Adding an OpenID Connect server to your application **allows you to support token authentication**. -It also allows you to manage all your users using local password or an external identity provider (e.g. Facebook or Google) for all your -applications in one central place, with the power to control who can access your API and the information that is exposed to each client. +In 2020, ASOS was merged into OpenIddict 3.0 to form a unified stack under the OpenIddict umbrella, while still offering an easy-to-use approach for new users +and a low-level experience for advanced users thanks to a "degraded mode" that allows using OpenIddict in a stateless way (i.e without a backing database). + +As part of this process, native support for `Microsoft.Owin` was added to OpenIddict 3.0 to allow using it in legacy ASP.NET 4.6.1 (and higher) applications, +making it an excellent candidate for replacing `OAuthAuthorizationServerMiddleware` and `OAuthBearerAuthenticationMiddleware` without having to migrate to ASP.NET Core. + +## Core concepts + +### User authentication + +Unlike other solutions, **OpenIddict exclusively focuses on the OAuth 2.0/OpenID Connect protocol aspects of the authorization process** +and leaves user authentication up to the implementer: OpenIddict can be natively used with any form of user authentication like password, token, +federated or Integration Windows Authentication. While convenient, using a membership stack like ASP.NET Core Identity is not required. + +Integration with OpenIddict is typically done by enabling the pass-through mode to handle requests in a controller action +or in a minimal API handler or, for more complex scenarios, by directly using its advanced events model. + +### Pass-through mode + +As with `OAuthAuthorizationServerMiddleware`, OpenIddict allows handling authorization, logout and token requests in custom controller actions or any other +middleware able to hook into the ASP.NET Core or OWIN request processing pipeline. In this case, OpenIddict will always validate incoming requests first +(e.g by ensuring the mandatory parameters are present and valid) before allowing the rest of the pipeline to be invoked: should any validation error occur, +OpenIddict will automatically reject the request before it reaches user-defined controller actions or custom middleware. + +```csharp +builder.Services.AddOpenIddict() + .AddServer(options => + { + // Enable the authorization and token endpoints. + options.SetAuthorizationEndpointUris("/authorize") + .SetTokenEndpointUris("/token"); + + // Enable the authorization code flow. + options.AllowAuthorizationCodeFlow(); + + // Register the signing and encryption credentials. + options.AddDevelopmentEncryptionCertificate() + .AddDevelopmentSigningCertificate(); + + // Register the ASP.NET Core host and configure the authorization endpoint + // to allow the /authorize minimal API handler to handle authorization requests + // after being validated by the built-in OpenIddict server event handlers. + // + // Token requests will be handled by OpenIddict itself by reusing the identity + // created by the /authorize handler and stored in the authorization codes. + options.UseAspNetCore() + .EnableAuthorizationEndpointPassthrough(); + }); +``` + +```csharp +app.MapGet("/authorize", async (HttpContext context) => +{ + // 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. + var principal = (await context.AuthenticateAsync(SteamAuthenticationDefaults.AuthenticationScheme))?.Principal; + if (principal is null) + { + return Results.Challenge(properties: null, new[] { SteamAuthenticationDefaults.AuthenticationScheme }); + } + + var identifier = principal.FindFirst(ClaimTypes.NameIdentifier)!.Value; + + // Create a new identity and import a few select claims from the Steam principal. + var identity = new ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType); + identity.AddClaim(new Claim(Claims.Subject, identifier)); + identity.AddClaim(new Claim(Claims.Name, identifier).SetDestinations(Destinations.AccessToken)); + + return Results.SignIn(new ClaimsPrincipal(identity), properties: null, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); +}); +``` + +### Events model + +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: + +```csharp +/// +/// Contains the logic responsible of rejecting authorization requests that don't specify a valid prompt parameter. +/// +public class ValidatePromptParameter : IOpenIddictServerHandler +{ + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictServerHandlerDescriptor Descriptor { get; } + = OpenIddictServerHandlerDescriptor.CreateBuilder() + .UseSingletonHandler() + .SetOrder(ValidateNonceParameter.Descriptor.Order + 1_000) + .SetType(OpenIddictServerHandlerType.BuiltIn) + .Build(); + + /// + public ValueTask HandleAsync(ValidateAuthorizationRequestContext context) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + // Reject requests specifying prompt=none with consent/login or select_account. + if (context.Request.HasPrompt(Prompts.None) && (context.Request.HasPrompt(Prompts.Consent) || + context.Request.HasPrompt(Prompts.Login) || + context.Request.HasPrompt(Prompts.SelectAccount))) + { + context.Logger.LogInformation(SR.GetResourceString(SR.ID6040)); + + context.Reject( + error: Errors.InvalidRequest, + description: SR.FormatID2052(Parameters.Prompt), + uri: SR.FormatID8000(SR.ID2052)); + + return default; + } + + return default; + } +} +``` + +In OpenIddict itself, event handlers are typically defined as dedicated classes but they can also be registered using delegates: + +```csharp +services.AddOpenIddict() + .AddServer(options => + { + options.AddEventHandler(builder => + builder.UseInlineHandler(context => + { + // Attach custom metadata to the configuration document. + context.Metadata["custom_metadata"] = 42; + + return default; + })); + }); +``` diff --git a/guides/migration/20-to-30.md b/guides/migration/20-to-30.md index 7b5c1d8..caa494d 100644 --- a/guides/migration/20-to-30.md +++ b/guides/migration/20-to-30.md @@ -46,9 +46,15 @@ and are no longer supported. Make sure your application (or intermediate librari ## Update the references to the Entity Framework Core/Entity Framework 6/MongoDB models -If your application references the `OpenIddictApplication`, `OpenIddictAuthorization`, `OpenIddictScope` or `OpenIddictToken` models, update these reference to use -their new names: `OpenIddict[provider name]Application`, `OpenIddict[provider name]Authorization`, `OpenIddict[provider name]Scope` and `OpenIddict[provider name]Token` -(e.g when using MongoDB: `OpenIddictMongoDbApplication`, `OpenIddictMongoDbAuthorization`, `OpenIddictMongoDbScope` and `OpenIddictMongoDbToken`). +If your application references the `OpenIddictApplication`, `OpenIddictAuthorization`, `OpenIddictScope` or `OpenIddictToken` models, +update these reference to use their new names: + +| Old name | New name (Entity Framework Core) | New name (Entity Framework 6) | New name (MongoDB) | +|-------------------------|--------------------------------------------|----------------------------------------|--------------------------------| +| OpenIddictApplication | OpenIddictEntityFrameworkCoreApplication | OpenIddictEntityFrameworkApplication | OpenIddictMongoDbApplication | +| OpenIddictAuthorization | OpenIddictEntityFrameworkCoreAuthorization | OpenIddictEntityFrameworkAuthorization | OpenIddictMongoDbAuthorization | +| OpenIddictScope | OpenIddictEntityFrameworkCoreScope | OpenIddictEntityFrameworkScope | OpenIddictMongoDbScope | +| OpenIddictToken | OpenIddictEntityFrameworkCoreToken | OpenIddictEntityFrameworkToken | OpenIddictMongoDbToken | ## Enable ASP.NET Core integration in the server and validation options @@ -213,5 +219,6 @@ services.AddOpenIddict() New response type permissions - enforced by default - [have been introduced in 3.0](/configuration/application-permissions.html#response-type-permissions). -If you have many applications to migrate, you can use [this script](https://github.com/openiddict/openiddict-core/issues/1138#issuecomment-713681158) -to infer appropriate response type permissions using the already granted grant types. +> [!NOTE] +> If you have many applications to migrate, you can use [this script](https://github.com/openiddict/openiddict-core/issues/1138#issuecomment-713681158) +> to infer appropriate response type permissions using the already granted grant types. diff --git a/index.md b/index.md index bb300b0..fe96b0c 100644 --- a/index.md +++ b/index.md @@ -1,38 +1,151 @@ > [!NOTE] > This documentation is a work-in-progress. To contribute, please visit https://github.com/openiddict/openiddict-documentation. -# OpenIddict: the OpenID Connect stack you'll be addicted to +# What's OpenIddict? OpenIddict aims at providing a **versatile solution** to implement an **OpenID Connect server and token validation in any ASP.NET Core 2.1 (and higher) application**. **ASP.NET 4.6.1 (and higher) applications are also fully supported thanks to a native Microsoft.Owin 4.2 integration**. -OpenIddict fully supports the **[code/implicit/hybrid flows](https://openid.net/specs/openid-connect-core-1_0.html)**, the **[client credentials/resource owner password grants](https://tools.ietf.org/html/rfc6749)** and the [device authorization flow](https://tools.ietf.org/html/rfc8628). You can also create your own custom grant types. +OpenIddict fully supports the **[code/implicit/hybrid flows](http://openid.net/specs/openid-connect-core-1_0.html)**, +the **[client credentials/resource owner password grants](https://tools.ietf.org/html/rfc6749)** and the [device authorization flow](https://tools.ietf.org/html/rfc8628). -OpenIddict natively supports **[Entity Framework Core](https://www.nuget.org/packages/OpenIddict.EntityFrameworkCore)**, **[Entity Framework 6](https://www.nuget.org/packages/OpenIddict.EntityFramework)** and **[MongoDB](https://www.nuget.org/packages/OpenIddict.MongoDb)** out-of-the-box, but you can also provide your own stores. +OpenIddict natively supports **[Entity Framework Core](https://www.nuget.org/packages/OpenIddict.EntityFrameworkCore)**, +**[Entity Framework 6](https://www.nuget.org/packages/OpenIddict.EntityFramework)** and **[MongoDB](https://www.nuget.org/packages/OpenIddict.MongoDb)** +out-of-the-box and custom stores can be implemented to support other providers. -
-
-
-
-

Introduction

-

Read an introduction on OpenIddict and the reason it was created.

-
-
-
-
-
-
-

Getting started

-

Get started quickly by working through this step-by-step guide.

-
-
-
-
-
-
-

Samples

-

View samples implementing the various authorization flows.

-
-
-
-
+# Getting started + +**Developers looking for a simple and turnkey solution are strongly encouraged to use [OrchardCore and its OpenID module](https://docs.orchardcore.net/en/dev/docs/reference/modules/OpenId/)**, +which is based on OpenIddict, comes with sensible defaults and offers a built-in management GUI to easily register OpenID client applications. + +**To implement a custom OpenID Connect server using OpenIddict, read [Getting started](~/guides/getting-started.md)**. + +**Samples demonstrating how to use OpenIddict with the different OAuth 2.0/OpenID Connect flows** +can be found in the [dedicated repository](https://github.com/openiddict/openiddict-samples). + +# Compatibility matrix + +| Web framework version | .NET runtime version | OpenIddict 3.x | OpenIddict 4.x (preview) | +|-----------------------|----------------------|-----------------------------------------|-----------------------------------------| +| ASP.NET Core 2.1 | .NET Framework 4.6.1 | :heavy_check_mark: :information_source: | :heavy_check_mark: :information_source: | +| ASP.NET Core 2.1 | .NET Framework 4.7.2 | :heavy_check_mark: | :heavy_check_mark: | +| ASP.NET Core 2.1 | .NET Framework 4.8 | :heavy_check_mark: | :heavy_check_mark: | +| ASP.NET Core 2.1 | .NET Core 2.1 | :heavy_check_mark: | :exclamation: | +| | | | | +| ASP.NET Core 3.1 | .NET Core 3.1 | :heavy_check_mark: | :heavy_check_mark: | +| | | | | +| ASP.NET Core 5.0 | .NET 5.0 | :heavy_check_mark: | :heavy_check_mark: | +| ASP.NET Core 6.0 | .NET 6.0 | :heavy_check_mark: | :heavy_check_mark: | +| | | | | +| Microsoft.Owin 4.2 | .NET Framework 4.6.1 | :heavy_check_mark: :information_source: | :heavy_check_mark: :information_source: | +| Microsoft.Owin 4.2 | .NET Framework 4.7.2 | :heavy_check_mark: | :heavy_check_mark: | +| Microsoft.Owin 4.2 | .NET Framework 4.8 | :heavy_check_mark: | :heavy_check_mark: | + +:exclamation: **Note: ASP.NET Core 2.1 on .NET Core 2.1 is no longer supported. While OpenIddict 4.x can still be used on .NET Core 2.1 +thanks to its .NET Standard 2.0 compatibility, users are strongly encouraged to migrate to ASP.NET Core/.NET 6.0**. +ASP.NET Core 2.1 on .NET Framework 4.6.1 (and higher) is still fully supported. + +:information_source: **Note: the following features are not available when targeting .NET Framework 4.6.1**: + - X.509 development encryption/signing certificates: calling `AddDevelopmentEncryptionCertificate()` or `AddDevelopmentSigningCertificate()` +will result in a `PlatformNotSupportedException` being thrown at runtime if no valid development certificate can be found and a new one must be generated. + - X.509 ECDSA signing certificates/keys: calling `AddSigningCertificate()` or `AddSigningKey()` +with an ECDSA certificate/key will always result in a `PlatformNotSupportedException` being thrown at runtime. + +# Certification + +Unlike many other identity providers, **OpenIddict is not a turnkey solution but a framework that requires writing custom code** +to be operational (typically, at least an authorization controller), making it a poor candidate for the certification program. + +While a reference implementation could be submitted as-is, **this wouldn't guarantee that implementations deployed by OpenIddict users would be standard-compliant.** + +Instead, **developers are encouraged to execute the conformance tests against their own deployment** once they've implemented their own logic. + +> The samples repository contains [a dedicated sample](https://github.com/openiddict/openiddict-samples/tree/dev/samples/Contruum/Contruum.Server) specially designed to be used +> with the OpenID Connect Provider Certification tool and demonstrate that OpenIddict can be easily used in a certified implementation. To allow executing the certification tests +> as fast as possible, that sample doesn't include any membership or consent feature (two hardcoded identities are proposed for tests that require switching between identities). + +-------------- + +# Resources + +**Looking for additional resources to help you get started with OpenIddict?** Don't miss these interesting blog posts: + +- **[Secure a Blazor WASM ASP.NET Core hosted APP using BFF and OpenIddict](https://damienbod.com/2022/01/03/secure-a-blazor-wasm-asp-net-core-hosted-app-using-bff-and-openiddict/)** by [Damien Bowden](https://github.com/damienbod) +- **[How to Secure ASP.NET Core Applications with OpenIddict Using Virto Commerce B2B eCommerce: Tech Case Study](https://virtocommerce.com/blog/how-to-secure-aspnet-core-applications-with-openiddict-using-virto-commerce-platform)** by [Virto Commerce](https://virtocommerce.com/) +- **[OpenIddict 3.0 general availability](https://kevinchalet.com/2020/12/23/openiddict-3-0-general-availability/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[Setting up an Authorization Server with OpenIddict](https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-i-introduction-4jid)** by [Robin van der Knaap](https://dev.to/robinvanderknaap) +- **[Introducing OpenIddict 3.0's first release candidate version](https://kevinchalet.com/2020/11/17/introducing-openiddict-3-0-s-first-release-candidate-version/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[OpenIddict 3.0 beta6 is out](https://kevinchalet.com/2020/10/27/openiddict-3-0-beta6-is-out/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[Introducing Quartz.NET support and new languages in OpenIddict 3.0 beta4](https://kevinchalet.com/2020/10/02/introducing-quartz-net-support-and-new-languages-in-openiddict-3-0-beta4/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[Introducing localization support in OpenIddict 3.0 beta3](https://kevinchalet.com/2020/08/03/introducing-localization-support-in-openiddict-3-0-beta3/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[OpenIddict 3.0 beta2 is out](https://kevinchalet.com/2020/07/08/openiddict-3-0-beta2-is-out/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[Introducing OpenIddict 3.0 beta1](https://kevinchalet.com/2020/06/11/introducing-openiddict-3-0-beta1/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[Adding OpenIddict 3.0 to an OWIN application](https://kevinchalet.com/2020/03/03/adding-openiddict-3-0-to-an-owin-application/)** by [Kévin Chalet](https://github.com/kevinchalet) +- **[Creating an OpenID Connect server proxy with OpenIddict 3.0's degraded mode](https://kevinchalet.com/2020/02/18/creating-an-openid-connect-server-proxy-with-openiddict-3-0-s-degraded-mode/)** by [Kévin Chalet](https://github.com/kevinchalet) + +**OpenIddict-based projects maintained by third parties**: + +- **[OrchardCore OpenID module](https://github.com/OrchardCMS/OrchardCore)**: turnkey OpenID Connect server and token validation solution, built with multitenancy in mind +- **[OpenIddict UI](https://github.com/thomasduft/openiddict-ui)** by [Thomas Duft](https://github.com/thomasduft): headless UI for managing client applications and scopes +- **[P41.OpenIddict.CouchDB](https://github.com/panoukos41/couchdb-openiddict)** by [Panos Athanasiou](https://github.com/panoukos41): CouchDB stores for OpenIddict + +# Security policy + +Security issues and bugs should be reported privately by emailing security@openiddict.com. +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. + +# Support + +If you need support, please make sure you [sponsor the project](https://github.com/sponsors/kevinchalet) before creating a GitHub ticket. +If you're not a sponsor, you can post your questions on Gitter or StackOverflow: + +- **Gitter: [https://gitter.im/openiddict/openiddict-core](https://gitter.im/openiddict/openiddict-core)** +- **StackOverflow: [https://stackoverflow.com/questions/tagged/openiddict](https://stackoverflow.com/questions/tagged/openiddict)** + +# Nightly builds + +If you want to try out the latest features and bug fixes, there is a MyGet feed with nightly builds of OpenIddict. +To reference the OpenIddict MyGet feed, **create a `NuGet.config` file** (at the root of your solution): + +```xml + + + + + + + +``` + +# Contributors + +**OpenIddict** is actively maintained by **[Kévin Chalet](https://github.com/kevinchalet)**. Contributions are welcome and can be submitted using pull requests. + +**Special thanks to our sponsors for their incredible support**: + +- [Sébastien Ros](https://github.com/sebastienros) +- [mridentity](https://github.com/mridentity) +- [Andrew](https://github.com/GDreyV) +- [gustavdw](https://github.com/gustavdw) +- [Gillardo](https://github.com/Gillardo) +- [Dovydas Navickas](https://github.com/DovydasNavickas) +- [Christian Schmitt](https://github.com/schmitch) +- [Thomas W](https://github.com/ThreeScreenStudios) +- [torfikarl](https://github.com/torfikarl) +- [Lewis Cianci](https://github.com/lewcianci) +- [Florian Wachs](https://github.com/florianwachs) +- [Vasko Poposki](https://github.com/vaspop) +- [Sebastian Stehle](https://github.com/SebastianStehle) +- [Michael Hochriegl](https://github.com/MichaelHochriegl) +- [sunielreddy](https://github.com/sunielreddy) +- [Communicatie Cockpit](https://github.com/communicatie-cockpit) +- [Keith Turner](https://github.com/KeithT) +- [WGMurray](https://github.com/WGMurray) +- [Thomas Bjallas](https://github.com/ThomasBjallas) +- [Pablo Pioli](https://github.com/pablopioli) +- [Michael Calasanz](https://github.com/mcalasa) + +# License + +This project is licensed under the **Apache License**. This means that you can use, modify and distribute it freely. +See [http://www.apache.org/licenses/LICENSE-2.0.html](http://www.apache.org/licenses/LICENSE-2.0.html) for more details. \ No newline at end of file diff --git a/templates/discordfx/styles/discord.css b/templates/discordfx/styles/discord.css index 3dc6326..7a8b95c 100644 --- a/templates/discordfx/styles/discord.css +++ b/templates/discordfx/styles/discord.css @@ -156,6 +156,11 @@ a.active, a:active overflow-y: hidden; } +.content +{ + text-align: justify; +} + .page-title { margin-block-start: 0; diff --git a/toc.yml b/toc.yml index 0478206..fb91d58 100644 --- a/toc.yml +++ b/toc.yml @@ -1,4 +1,4 @@ -- name: User guides +- name: Guides href: guides/ - name: Configuration