private async Task <AuthenticationTicket> CreateTicketAsync(
            OpenIdConnectRequest request,
            ApplicationUser user,
            AuthenticationProperties properties = null)
        {
            // Create a new ClaimsPrincipal containing the claims that
            // will be used to create an id_token, a token or a code.
            var principal = await signInManager.CreateUserPrincipalAsync(user);

            // Create a new authentication ticket holding the user identity.
            var ticket = new AuthenticationTicket(principal, properties,
                                                  OpenIdConnectServerDefaults.AuthenticationScheme);

            if (!request.IsAuthorizationCodeGrantType())
            {
                ticket.SetScopes(new[] { OpenIdConnectConstants.Scopes.OfflineAccess }
                                 .Concat(scopes.GetScopes())
                                 .Intersect(request.GetScopes()));
            }

            ticket.SetResources("resource_server");

            // Note: by default, claims are NOT automatically included in the access and identity tokens.
            // To allow OpenIddict to serialize them, you must attach them a destination, that specifies
            // whether they should be included in access tokens, in identity tokens or in both.

            foreach (var claim in ticket.Principal.Claims)
            {
                // Never include the security stamp in the access and identity tokens, as it's a secret value.
                if (claim.Type == identityOptions.Value.ClaimsIdentity.SecurityStampClaimType)
                {
                    continue;
                }

                var destinations = new List <string>
                {
                    OpenIdConnectConstants.Destinations.AccessToken
                };

                // Only add the iterated claim to the id_token if the corresponding scope was granted to the client application.
                // The other claims will only be added to the access_token, which is encrypted when using the default format.
                if (claim.Type == OpenIdConnectConstants.Claims.Name &&
                    ticket.HasScope(OpenIdConnectConstants.Scopes.Profile) ||
                    claim.Type == OpenIdConnectConstants.Claims.Email &&
                    ticket.HasScope(OpenIdConnectConstants.Scopes.Email) ||
                    claim.Type == OpenIdConnectConstants.Claims.Role &&
                    ticket.HasScope(OpenIddictConstants.Claims.Roles))
                {
                    destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken);
                }

                claim.SetDestinations(destinations);
            }

            return(ticket);
        }
        public async Task InitializeAsync()
        {
            //if (await manager.FindByClientIdAsync("react") == null)
            //{
            //    var descriptor = new OpenIddictApplicationDescriptor
            //    {
            //        ClientId = "react",
            //        ClientSecret = "react_secret",
            //        DisplayName = "SPA client application",
            //        PostLogoutRedirectUris = { new Uri("http://localhost:3000/signout-callback-oidc") },
            //        RedirectUris = { new Uri("http://localhost:3000/signin-oidc") },
            //        Permissions =
            //        {
            //            OpenIddictConstants.Permissions.Endpoints.Authorization,
            //            OpenIddictConstants.Permissions.Endpoints.Logout,
            //            OpenIddictConstants.Permissions.GrantTypes.Implicit
            //        }
            //    };

            //    await manager.CreateAsync(descriptor);
            //}

            var resourceServer = await manager.FindByClientIdAsync("resource_server");

            if (resourceServer == null)
            {
                var descriptor = new OpenIddictApplicationDescriptor
                {
                    ClientId     = "resource_server",
                    ClientSecret = "resource_server_secret",
                    Permissions  =
                    {
                        OpenIddictConstants.Permissions.Endpoints.Token,
                        OpenIddictConstants.Permissions.GrantTypes.ClientCredentials
                    }
                };

                await manager.CreateAsync(descriptor);
            }

            var mvcClient = await manager.FindByClientIdAsync("mvc_client");

            if (mvcClient == null)
            {
                var descriptor = new OpenIddictApplicationDescriptor
                {
                    ClientId               = "mvc_client",
                    ClientSecret           = "mvc_client_secret",
                    DisplayName            = "MVC Client application",
                    PostLogoutRedirectUris = { new Uri($"{configuration["Client:BaseUrl"]}external/logout") },
                    RedirectUris           = { new Uri($"{configuration["Client:BaseUrl"]}external/login") },
                    Permissions            =
                    {
                        OpenIddictConstants.Permissions.Endpoints.Authorization,
                        OpenIddictConstants.Permissions.Endpoints.Logout,
                        OpenIddictConstants.Permissions.Endpoints.Token,
                        OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
                        OpenIddictConstants.Permissions.GrantTypes.RefreshToken
                    }
                };

                foreach (var scope in scopes.GetScopes())
                {
                    descriptor.Permissions.Add($"scp:{scope}");
                }

                await manager.CreateAsync(descriptor);
            }
            else
            {
                var permissions = new JArray(
                    OpenIddictConstants.Permissions.Endpoints.Authorization,
                    OpenIddictConstants.Permissions.Endpoints.Logout,
                    OpenIddictConstants.Permissions.Endpoints.Token,
                    OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
                    OpenIddictConstants.Permissions.GrantTypes.RefreshToken);

                foreach (var scope in scopes.GetScopes())
                {
                    permissions.Add($"scp:{scope}");
                }

                mvcClient.Permissions = JsonConvert.SerializeObject(permissions);
                await manager.UpdateAsync(mvcClient);
            }

            var swagger = await manager.FindByClientIdAsync("swagger");

            if (swagger == null)
            {
                var descriptor = new OpenIddictApplicationDescriptor
                {
                    ClientId     = "swagger",
                    DisplayName  = "Swagger",
                    RedirectUris = { new Uri(Combine(addressResolver.Resolve(), "/swagger/oauth2-redirect.html")) },
                    Permissions  =
                    {
                        OpenIddictConstants.Permissions.Endpoints.Authorization,
                        OpenIddictConstants.Permissions.GrantTypes.Implicit
                    }
                };

                foreach (var scope in scopes.GetScopes())
                {
                    descriptor.Permissions.Add($"scp:{scope}");
                }

                await manager.CreateAsync(descriptor);
            }
            else
            {
                var permissions = new JArray(OpenIddictConstants.Permissions.Endpoints.Authorization, OpenIddictConstants.Permissions.GrantTypes.Implicit);
                foreach (var scope in scopes.GetScopes())
                {
                    permissions.Add($"scp:{scope}");
                }

                swagger.Permissions = JsonConvert.SerializeObject(permissions);
                await manager.UpdateAsync(swagger);
            }
        }