0
mc86 created
HI: I had my customgrant named EmployeeNumberGrant `public class EmployeeNumberGrant : ITokenExtensionGrant { public const string ExtensionGrantName = "employee_number";
public string Name => ExtensionGrantName;
private IdentityUserManager _userManager;
private IUserClaimsPrincipalFactory<IdentityUser> _claimsFactory;
private AbpOpenIddictClaimsPrincipalManager _claimsPrincipalManager;
private AbpSignInManager _signInManager;
public EmployeeNumberGrant(
IdentityUserManager userManager,
IUserClaimsPrincipalFactory<IdentityUser> claimsFactory,
AbpOpenIddictClaimsPrincipalManager claimsPrincipalManager)
{
_userManager = userManager;
_claimsFactory = claimsFactory;
_claimsPrincipalManager = claimsPrincipalManager;
}
public EmployeeNumberGrant()
{
}
public async Task<IActionResult> HandleAsync(ExtensionGrantContext context)
{
_userManager = context.HttpContext.RequestServices.GetRequiredService<IdentityUserManager>();
_claimsFactory = context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<IdentityUser>>();
_claimsPrincipalManager = context.HttpContext.RequestServices.GetRequiredService<AbpOpenIddictClaimsPrincipalManager>();
_signInManager= context.HttpContext.RequestServices.GetRequiredService<AbpSignInManager>();
var empNo = context.Request.GetParameter("employee_number")?.ToString();
var ts = context.Request.GetParameter("timestamp")?.ToString();
var signature = context.Request.GetParameter("signature")?.ToString();
if (string.IsNullOrEmpty(empNo) || string.IsNullOrEmpty(ts) || string.IsNullOrEmpty(signature))
{
return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Missing parameters."
}));
}
// 1. 校验时间戳
if (!long.TryParse(ts, out var ticks) ||
DateTime.UtcNow - new DateTime(ticks, DateTimeKind.Utc) > TimeSpan.FromMinutes(5))
{
return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Expired timestamp."
}));
}
// 2. 校验签名
var raw = $"{empNo}:{ts}";
if (!VerifySignature(raw, signature, "SuperSecretSharedKey123!"))
{
return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Invalid signature."
}));
}
// 3. 查找用户
var user = await _userManager.FindByNameAsync(empNo);
if (user == null)
{
return new ForbidResult(new[] { OpenIddictServerAspNetCoreDefaults.AuthenticationScheme },
new AuthenticationProperties(new Dictionary<string, string>
{
[OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "User not found."
}));
}
// 4. 创建 ClaimsPrincipal
var principal = await _claimsFactory.CreateAsync(user);
// 附加自定义 Claim
((ClaimsIdentity)principal.Identity!).AddClaim("employee_number", empNo);
// 设置 scopes
var scopes = new[] {"profile", "roles", "email", "phone", "offline_access", "master9" }.ToImmutableArray();
principal.SetScopes(scopes);
// 关联资源
var resources = new List<string>();
await foreach (var resource in context.HttpContext.RequestServices
.GetRequiredService<IOpenIddictScopeManager>()
.ListResourcesAsync(scopes))
{
resources.Add(resource);
}
principal.SetResources(resources);
principal.SetAudiences("Master9");
// 交给 ABP 内置 ClaimsPrincipalManager 处理(角色、权限等)
await _claimsPrincipalManager.HandleAsync(context.Request, principal);
//principal.SetScopes(context.Request.GetScopes());
// await _signInManager.SignInAsync(user, isPersistent: false);
return new SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, principal);
}
private static bool VerifySignature(string raw, string signature, string secretKey)
{
using var hmac = new System.Security.Cryptography.HMACSHA256(System.Text.Encoding.UTF8.GetBytes(secretKey));
var hash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(raw));
var expected = Convert.ToBase64String(hash);
return expected == signature;
}
}`
now I don't know how to make blazor app login with this grant.