You can also make it simple.
public class PasswordlessExtensionGrant : ITokenExtensionGrant { public const string ExtensionGrantName = "PasswordlessExtensionGrant"; public string Name => ExtensionGrantName; public async Task<IActionResult> HandleAsync(ExtensionGrantContext context) { // get phone number from request var phoneNumber = context.Request.GetParameter("phoneNumber")?.Value?.ToString(); if (string.IsNullOrEmpty(phoneNumber)) { return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme }, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant }!)); } // retrieve user var userRepository = context.HttpContext.RequestServices.GetRequiredService<IRepository<IdentityUser, Guid>>(); var user = await userRepository.FirstOrDefaultAsync(x => x.PhoneNumber == phoneNumber); if (user == null) { return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme }, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant }!)); } var principal = await context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<IdentityUser>>().CreateAsync(user); // retrieve generic user claims var userClaimsPrincipalFactory = context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<IdentityUser>>(); var claimsPrincipal = await userClaimsPrincipalFactory.CreateAsync(user); claimsPrincipal.SetScopes(principal.GetScopes()); claimsPrincipal.SetResources(await GetResourcesAsync(context, principal.GetScopes())); // retrieve abp user claims var abpClaimsPrincipalFactory = context.HttpContext.RequestServices.GetRequiredService<IAbpClaimsPrincipalFactory>(); var abpClaimsPrincipal = await abpClaimsPrincipalFactory.CreateAsync(claimsPrincipal); await context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>().HandleAsync(context.Request, abpClaimsPrincipal); return new SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, abpClaimsPrincipal); } private async Task<IEnumerable<string>> GetResourcesAsync(ExtensionGrantContext context, ImmutableArray<string> scopes) { var resources = new List<string>(); if (!scopes.Any()) { return resources; } await foreach (var resource in context.HttpContext.RequestServices.GetRequiredService<IOpenIddictScopeManager>().ListResourcesAsync(scopes)) { resources.Add(resource); } return resources; } }
I noticed the scope of this token is a bit limited. Could we look into adding more scope to it? This way, we can ensure it meets all our needs more effectively. Thanks for considering this!
yes @maliming, pls check your mail
hi @maliming, do you have any ideas?
In our authentication server project, I've added the setup and grant type configurations like above image. However, when I attempt to run the API through the endpoint 'domain/connect/token', I encounter an issue.
I'm using a new grant type, and it's working wonderfully. Thank you so much for your help!
Hello,
I've retrieved the client_id and client_secret from OpenIddictApplications, but I'm running into a snag: I keep getting an error that says "The specified client credentials are invalid." Do you have any idea what might be causing this?
Additionally, I could use some guidance on how to generate the token and include it in the payload.