Beispiel #1
0
        private async Task<AuthenticateResult> CreateTicketAsync(string payload)
        {
            // Note: the token manager is deliberately not injected using constructor injection
            // to allow using the validation handler without having to register the core services.
            var manager = Context.RequestServices.GetService<IOpenIddictTokenManager>();
            if (manager == null)
            {
                throw new InvalidOperationException(new StringBuilder()
                    .AppendLine("The core services must be registered when enabling reference tokens support.")
                    .Append("To register the OpenIddict core services, use 'services.AddOpenIddict().AddCore()'.")
                    .ToString());
            }

            // Retrieve the token entry from the database. If it
            // cannot be found, assume the token is not valid.
            var token = await manager.FindByReferenceIdAsync(payload);
            if (token == null)
            {
                return AuthenticateResult.Fail("Authentication failed because the access token cannot be found in the database.");
            }

            // Extract the encrypted payload from the token. If it's null or empty,
            // assume the token is not a reference token and consider it as invalid.
            var ciphertext = await manager.GetPayloadAsync(token);
            if (string.IsNullOrEmpty(ciphertext))
            {
                return AuthenticateResult.Fail("Authentication failed because the access token is not a reference token.");
            }

            var ticket = Options.AccessTokenFormat.Unprotect(ciphertext);
            if (ticket == null)
            {
                return AuthenticateResult.Fail(
                    "Authentication failed because the reference token cannot be decrypted. " +
                    "This may indicate that the token entry is corrupted or tampered.");
            }

            // Dynamically set the creation and expiration dates.
            ticket.Properties.IssuedUtc = await manager.GetCreationDateAsync(token);
            ticket.Properties.ExpiresUtc = await manager.GetExpirationDateAsync(token);

            // Restore the token and authorization identifiers attached with the database entry.
            ticket.Properties.SetProperty(OpenIddictConstants.Properties.TokenId, await manager.GetIdAsync(token));
            ticket.Properties.SetProperty(OpenIddictConstants.Properties.AuthorizationId,
                await manager.GetAuthorizationIdAsync(token));

            if (Options.SaveToken)
            {
                // Store the access token in the authentication ticket.
                ticket.Properties.StoreTokens(new[]
                {
                    new AuthenticationToken { Name = OAuthValidationConstants.Properties.Token, Value = payload }
                });
            }

            // Resolve the primary identity associated with the principal.
            var identity = (ClaimsIdentity) ticket.Principal.Identity;

            // Copy the scopes extracted from the authentication ticket to the
            // ClaimsIdentity to make them easier to retrieve from application code.
            var scopes = ticket.Properties.GetProperty(OAuthValidationConstants.Properties.Scopes);
            if (!string.IsNullOrEmpty(scopes))
            {
                foreach (var scope in JArray.Parse(scopes).Values<string>())
                {
                    identity.AddClaim(new Claim(OAuthValidationConstants.Claims.Scope, scope));
                }
            }

            var notification = new CreateTicketContext(Context, Scheme, Options, ticket);
            await Events.CreateTicket(notification);

            if (notification.Result != null)
            {
                Logger.LogInformation("The default authentication handling was skipped from user code.");

                return notification.Result;
            }

            // Optimization: avoid allocating a new AuthenticationTicket
            // if the principal/properties instances were not replaced.
            if (ReferenceEquals(notification.Principal, ticket.Principal) &&
                ReferenceEquals(notification.Properties, ticket.Properties))
            {
                return AuthenticateResult.Success(ticket);
            }

            return AuthenticateResult.Success(new AuthenticationTicket(
                notification.Principal, notification.Properties, Scheme.Name));
        }
 /// <summary>
 /// Invoked when a ticket is to be created from an introspection response.
 /// </summary>
 public virtual Task CreateTicket(CreateTicketContext context) => OnCreateTicket(context);