From c24ded39ced8978e7e7aeedddf2380d06c99121d Mon Sep 17 00:00:00 2001 From: OpenIddict Bot <32257313+openiddict-bot@users.noreply.github.com> Date: Wed, 13 Jan 2021 04:49:17 +0000 Subject: [PATCH] Update the documentation pages --- guide/getting-started.html | 214 +++++++++++++++++++++---------------- guide/samples.html | 120 --------------------- guide/toc.html | 3 - index.html | 2 +- manifest.json | 23 ++-- 5 files changed, 130 insertions(+), 232 deletions(-) delete mode 100644 guide/samples.html diff --git a/guide/getting-started.html b/guide/getting-started.html index 8c3c2ae..eff565f 100644 --- a/guide/getting-started.html +++ b/guide/getting-started.html @@ -68,36 +68,28 @@

Getting started

-

To use OpenIddict, you need to:

+

To implement a custom OpenID Connect server using OpenIddict, the simplest option is to clone one of the official samples from the openiddict-samples repository.

+

If you don't want to start from one of the recommended samples, you'll need to:

    -
  • Install the latest .NET Core 2.x tooling and update your packages to reference the ASP.NET Core 2.x packages.

    +
  • Install the .NET Core 2.1.x, 3.1.x or .NET 5.0.x tooling.

  • -
  • Have an existing project or create a new one: when creating a new project using Visual Studio's default ASP.NET Core template, using individual user accounts authentication is strongly recommended. When updating an existing project, you must provide your own AccountController to handle the registration process and the authentication flow.

    +
  • Have an existing project or create a new one: when creating a new project using Visual Studio's default ASP.NET Core template, +using individual user accounts authentication is strongly recommended as it automatically includes the default ASP.NET Core Identity UI, based on Razor Pages.

  • Update your .csproj file to reference the OpenIddict packages:

    -
    <PackageReference Include="OpenIddict" Version="2.0.0-*" />
    -<PackageReference Include="OpenIddict.EntityFrameworkCore" Version="2.0.0-*" />
    +
    <PackageReference Include="OpenIddict.AspNetCore" Version="3.0.0" />
    +<PackageReference Include="OpenIddict.EntityFrameworkCore" Version="3.0.0" />
     
  • -
  • OPTIONAL: 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 version="1.0" encoding="utf-8"?>
    -<configuration>
    -    <packageSources>
    -        <add key="nuget" value="https://api.nuget.org/v3/index.json" />
    -        <add key="openiddict" value="https://www.myget.org/F/openiddict/api/v3/index.json" />
    -    </packageSources>
    -</configuration>
    -
  • -
  • Configure the OpenIddict services in Startup.ConfigureServices:

    +
  • Configure the OpenIddict core, server and validation services in Startup.ConfigureServices. +Here's an example for the client credentials grant, used in machine-to-machine scenarios:

    public void ConfigureServices(IServiceCollection services)
     {
    -    services.AddMvc();
    +    services.AddControllersWithViews();
     
         services.AddDbContext<ApplicationDbContext>(options =>
         {
             // Configure the context to use Microsoft SQL Server.
    -        options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"]);
    +        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
     
             // Register the entity sets needed by OpenIddict.
             // Note: use the generic overload if you need
    @@ -105,56 +97,74 @@ of OpenIddict.

    options.UseOpenIddict(); }); - // Register the Identity services. - services.AddIdentity<ApplicationUser, IdentityRole>() - .AddEntityFrameworkStores<ApplicationDbContext>() - .AddDefaultTokenProviders(); - - // Register the OpenIddict services. services.AddOpenIddict() + + // Register the OpenIddict core components. .AddCore(options => { - // Configure OpenIddict to use the Entity Framework Core stores and entities. + // Configure OpenIddict to use the Entity Framework Core stores and models. + // Note: call ReplaceDefaultEntities() to replace the default OpenIddict entities. options.UseEntityFrameworkCore() - .UseDbContext<ApplicationDbContext>(); + .UseDbContext<ApplicationDbContext>(); }) + // Register the OpenIddict server components. .AddServer(options => { - // Register the ASP.NET Core MVC binder used by OpenIddict. - // Note: if you don't call this method, you won't be able to - // bind OpenIdConnectRequest or OpenIdConnectResponse parameters. - options.UseMvc(); + // Enable the token endpoint. + options.SetTokenEndpointUris("/connect/token"); - // Enable the token endpoint (required to use the password flow). - options.EnableTokenEndpoint("/connect/token"); + // Enable the client credentials flow. + options.AllowClientCredentialsFlow(); - // Allow client applications to use the grant_type=password flow. - options.AllowPasswordFlow(); + // Register the signing and encryption credentials. + options.AddDevelopmentEncryptionCertificate() + .AddDevelopmentSigningCertificate(); - // During development, you can disable the HTTPS requirement. - options.DisableHttpsRequirement(); - - // Accept token requests that don't specify a client_id. - options.AcceptAnonymousClients(); + // Register the ASP.NET Core host and configure the ASP.NET Core-specific options. + options.UseAspNetCore() + .EnableTokenEndpointPassthrough(); }) - .AddValidation(); + // Register the OpenIddict validation components. + .AddValidation(options => + { + // Import the configuration from the local OpenIddict server instance. + options.UseLocalServer(); + + // Register the ASP.NET Core host. + options.UseAspNetCore(); + }); + + // Register the worker responsible of seeding the database with the sample clients. + // Note: in a real world application, this step should be part of a setup script. + services.AddHostedService<Worker>(); }
  • -
  • Make sure the authentication middleware is registered before all the other middleware, including app.UseMvc():

    +
  • Make sure the ASP.NET Core authentication middleware is correctly registered at the right place:

    public void Configure(IApplicationBuilder app)
     {
    -    app.UseAuthentication();
    +    app.UseDeveloperExceptionPage();
     
    -    app.UseMvc();
    +    app.UseRouting();
    +
    +    app.UseAuthentication();
    +    app.UseAuthorization();
    +
    +    app.UseEndpoints(options =>
    +    {
    +        options.MapControllers();
    +        options.MapDefaultControllerRoute();
    +    });
    +
    +    app.UseWelcomePage();
     }
     
  • Update your Entity Framework Core context registration to register the OpenIddict entities:

    services.AddDbContext<ApplicationDbContext>(options =>
     {
         // Configure the context to use Microsoft SQL Server.
    -    options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"]);
    +    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
     
         // Register the entity sets needed by OpenIddict.
         // Note: use the generic overload if you need
    @@ -163,7 +173,9 @@ of OpenIddict.

    });
-

Note: if you change the default entity primary key (e.g. to int or Guid instead of string), make sure you use the options.ReplaceDefaultEntities<TKey>() core extension accepting a TKey generic argument and use the generic options.UseOpenIddict<TKey>() overload to configure Entity Framework Core to use the specified key type:

+

-> [!NOTE]

+

Important: if you change the default entity primary key (e.g. to int or Guid instead of string), make sure you use the options.ReplaceDefaultEntities<TKey>() +core extension accepting a TKey generic argument and use the generic options.UseOpenIddict<TKey>() overload to configure Entity Framework Core to use the specified key type:

services.AddOpenIddict()
     .AddCore(options =>
     {
@@ -182,67 +194,85 @@ services.AddDbContext<ApplicationDbContext>(options =>
 });
 
    -
  • Create your own authorization controller:
  • -
-

To support the password or the client credentials flow, you must provide your own token endpoint action. -To enable authorization code/implicit flows support, you'll similarly have to create your own authorization endpoint action and your own views/view models.

-

The Mvc.Server sample comes with an AuthorizationController that supports both the password flow and the authorization code flow and that you can easily reuse in your application.

-
    -
  • Enable the corresponding flows in the OpenIddict options:

    -
    public void ConfigureServices(IServiceCollection services)
    +
  • Create your own authorization controller: +Implementing a custom authorization controller is required to allow OpenIddict to create tokens based on the identities and claims you provide. +Here's an example for the client credentials grant:

    +
    public class AuthorizationController : Controller
     {
    -    // Register the OpenIddict services.
    -    services.AddOpenIddict()
    -        .AddCore(options =>
    +    private readonly OpenIddictApplicationManager<OpenIddictEntityFrameworkCoreApplication> _applicationManager;
    +
    +    public AuthorizationController(OpenIddictApplicationManager<OpenIddictEntityFrameworkCoreApplication> applicationManager)
    +        => _applicationManager = applicationManager;
    +
    +    [HttpPost("~/connect/token"), Produces("application/json")]
    +    public async Task<IActionResult> Exchange()
    +    {
    +        var request = HttpContext.GetOpenIddictServerRequest();
    +        if (request.IsClientCredentialsGrantType())
             {
    -            // Configure OpenIddict to use the Entity Framework Core stores and entities.
    -            options.UseEntityFrameworkCore()
    -                   .UseDbContext<ApplicationDbContext>();
    -        })
    +            // Note: the client credentials are automatically validated by OpenIddict:
    +            // if client_id or client_secret are invalid, this action won't be invoked.
     
    -        .AddServer(options =>
    -        {
    -            // Register the ASP.NET Core MVC binder used by OpenIddict.
    -            // Note: if you don't call this method, you won't be able to
    -            // bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
    -            options.UseMvc();
    +            var application = await _applicationManager.FindByClientIdAsync(request.ClientId);
    +            if (application == null)
    +            {
    +                throw new InvalidOperationException("The application details cannot be found in the database.");
    +            }
     
    -            // Enable the authorization/token endpoints (required to use the code flow).
    -            options.EnableAuthorizationEndpoint("/connect/authorize")
    -                   .EnableTokenEndpoint("/connect/token");
    +            // Create a new ClaimsIdentity containing the claims that
    +            // will be used to create an id_token, a token or a code.
    +            var identity = new ClaimsIdentity(
    +                TokenValidationParameters.DefaultAuthenticationType,
    +                Claims.Name, Claims.Role);
     
    -            // Allow client applications to use the code flow.
    -            options.AllowAuthorizationCodeFlow();
    +            // Use the client_id as the subject identifier.
    +            identity.AddClaim(Claims.Subject, await _applicationManager.GetClientIdAsync(application),
    +                Destinations.AccessToken, Destinations.IdentityToken);
     
    -            // During development, you can disable the HTTPS requirement.
    -            options.DisableHttpsRequirement();
    -        })
    +            identity.AddClaim(Claims.Name, await _applicationManager.GetDisplayNameAsync(application),
    +                Destinations.AccessToken, Destinations.IdentityToken);
     
    -        .AddValidation();
    +            return SignIn(new ClaimsPrincipal(identity), OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
    +        }
    +
    +        throw new NotImplementedException("The specified grant type is not implemented.");
    +    }
     }
     
  • -
  • Register your client application:

    -
    // Create a new service scope to ensure the database context
    -// is correctly disposed when this methods returns.
    -using (var scope = app.ApplicationServices.CreateScope())
    +
  • Register your client application (e.g from an IHostedService implementation):

    +
    public class Worker : IHostedService
     {
    -    var provider = scope.ServiceProvider;
    -    var context = provider.GetRequiredService<ApplicationDbContext>();
    -    await context.Database.EnsureCreatedAsync();
    +    private readonly IServiceProvider _serviceProvider;
     
    -    var manager = provider.GetRequiredService<IOpenIddictApplicationManager>();
    +    public Worker(IServiceProvider serviceProvider)
    +        => _serviceProvider = serviceProvider;
     
    -    if (await manager.FindByClientIdAsync("[client identifier]") == null)
    +    public async Task StartAsync(CancellationToken cancellationToken)
         {
    -        var descriptor = new OpenIddictApplicationDescriptor
    -        {
    -            ClientId = "[client identifier]",
    -            ClientSecret = "[client secret]",
    -            RedirectUris = { new Uri("[redirect uri]") }
    -        };
    +        using var scope = _serviceProvider.CreateScope();
     
    -        await manager.CreateAsync(descriptor);
    +        var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
    +        await context.Database.EnsureCreatedAsync();
    +
    +        var manager = scope.ServiceProvider.GetRequiredService<OpenIddictApplicationManager<OpenIddictEntityFrameworkCoreApplication>>();
    +
    +        if (await manager.FindByClientIdAsync("console") is null)
    +        {
    +            await manager.CreateAsync(new OpenIddictApplicationDescriptor
    +            {
    +                ClientId = "console",
    +                ClientSecret = "388D45FA-B36B-4988-BA59-B187D329C207",
    +                DisplayName = "My client application",
    +                Permissions =
    +                {
    +                    Permissions.Endpoints.Token,
    +                    Permissions.GrantTypes.ClientCredentials
    +                }
    +            });
    +        }
         }
    +
    +    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
     }
     
diff --git a/guide/samples.html b/guide/samples.html deleted file mode 100644 index c8ccd32..0000000 --- a/guide/samples.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - Samples - - - - - - - - - - - - - - - -
-
- -
-
-
- - - - -
-
-
-
- -
-
-
-
-
- -
-
-
    -
  • -
-
-
-
-
- -
- Show / Hide Table of Contents -
-
-
-
-
-
-
-

Samples

- -

Specialized samples can be found in the samples repository:

-
    -
  • Authorization code flow sample
  • -
  • Implicit flow sample
  • -
  • Password flow sample
  • -
  • Client credentials flow sample
  • -
  • Refresh flow sample
  • -
-

Samples for ASP.NET Core 1.x can be found in the master branch of the samples repository.

-
-
-
- -
-
-
-
    -
  • - Improve this Doc -
  • -
-
-
-
In This Article
-
-
-
-
-
-
- -
-
-
-
- - Back to top - - - Generated by DocFX -
-
-
-
- - - - - - diff --git a/guide/toc.html b/guide/toc.html index bb1ab64..5572949 100644 --- a/guide/toc.html +++ b/guide/toc.html @@ -18,9 +18,6 @@
  • Getting started
  • -
  • - Samples -
  • Migration guide
  • diff --git a/index.html b/index.html index 5554da5..ace8c58 100644 --- a/index.html +++ b/index.html @@ -85,7 +85,7 @@ and starting in OpenIddict 3.0, any ASP.NET 4.x or OWIN application too<
    -

    Samples

    +

    Samples

    View samples implementing the various authorization flows.

    diff --git a/manifest.json b/manifest.json index a973a2d..e4e6fdd 100644 --- a/manifest.json +++ b/manifest.json @@ -45,7 +45,7 @@ "output": { ".html": { "relative_path": "guide/getting-started.html", - "hash": "ff7DWdjAwYucfbMQfCyTFg==" + "hash": "B+LUpBca5+kh6NFTvwCenQ==" } }, "is_incremental": false, @@ -75,25 +75,13 @@ "is_incremental": false, "version": "" }, - { - "type": "Conceptual", - "source_relative_path": "guide/samples.md", - "output": { - ".html": { - "relative_path": "guide/samples.html", - "hash": "wOuQoyk0yySl5WZajiENrA==" - } - }, - "is_incremental": false, - "version": "" - }, { "type": "Toc", "source_relative_path": "guide/toc.yml", "output": { ".html": { "relative_path": "guide/toc.html", - "hash": "epsbDuVdI5yEtqtUWQIS9g==" + "hash": "xm6nv4mvnxzUpj5meobWaQ==" } }, "is_incremental": false, @@ -122,12 +110,15 @@ "version": "" }, { + "log_codes": [ + "InvalidFileLink" + ], "type": "Conceptual", "source_relative_path": "index.md", "output": { ".html": { "relative_path": "index.html", - "hash": "gInpRdPv2JGMAzcpzWUKCw==" + "hash": "mf66lbYDYJ1ueuRq2UsFNQ==" } }, "is_incremental": false, @@ -160,7 +151,7 @@ "ConceptualDocumentProcessor": { "can_incremental": false, "incrementalPhase": "build", - "total_file_count": 7, + "total_file_count": 6, "skipped_file_count": 0 }, "ResourceDocumentProcessor": {