private AuthenticationTicket CreateTicket(OpenIdConnectRequest request, WindowsPrincipal principal)
    {
        // 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(OpenIdConnectServerDefaults.AuthenticationScheme);

        // Note: the ClaimTypes.NameIdentifier is required by OpenIddict
        // but is not automatically added to the Windows principal, so
        // the primary security identifier is used as a fallback value.
        identity.AddClaim(ClaimTypes.NameIdentifier, principal.GetClaim(ClaimTypes.PrimarySid));

        // 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 principal.Claims)
        {
            // In this sample, every claim is serialized in both the access and the identity tokens.
            // In a real world application, you'd probably want to exclude confidential claims
            // or apply a claims policy based on the scopes requested by the client application.
            claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken,
                                  OpenIdConnectConstants.Destinations.IdentityToken);

            // Copy the claim from the Windows principal to the new identity.
            identity.AddClaim(claim);
        }

        // Create a new authentication ticket holding the user identity.
        return(new AuthenticationTicket(
                   new ClaimsPrincipal(identity),
                   new AuthenticationProperties(),
                   OpenIdConnectServerDefaults.AuthenticationScheme));
    }