我怀疑这很简单,但是我找不到我需要做的事情。
我正在尝试使用名称/密码/ SomethingExtra启用密码授予,令牌终结点
所有功能都仅使用名称和密码即可。我可以在服务器上的acr_values中看到“ Data:SomethingExtra”,但只能在GetProfileDataAsync覆盖中看到。
因此,我可以在令牌生成(GetProfileDataAsync)中获取acr_values,但是我想用这些额外的数据“验证”用户。如何在验证时测试我的acr_values?
我怀疑有一种方法可以覆盖额外的acr_values来获取“登录请求”,因此我可以决定返回令牌或拒绝访问,与使用Quickstart网页进行交互式登录一样。
但是我要覆盖哪些值才能对3个值进行身份验证?
答案 0 :(得分:0)
如果您正在使用密码授予,那么您将实现IResourceOwnerPasswordValidator
来验证密码。您可以在此类中获得acr值,如下所示:
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) {
string acrValues = context.Request.Raw.Get("acr_values");
IEnumerable<string> values = acrValues.Trim().Split(new[] { ' ' });
string extraDataAcr = values.FirstOrDefault(x => x.StartsWith("ExtraData:"));
string extraDataValue extraDataAcr?.Substring("ExtraData:".Length);
答案 1 :(得分:0)
经过一番挖掘...可能会节省一些时间
public class ACustomTokenRequestValidator : ICustomTokenRequestValidator
{
private readonly UserManager<ApplicationUser> _userManager;
public ACustomTokenRequestValidator(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task ValidateAsync(CustomTokenRequestValidationContext context)
{
if (context?.Result?.ValidatedRequest?.GrantType != null &&
context.Result.ValidatedRequest.GrantType.ToUpper() == "PASSWORD") // Only interested in password Grant
{
var acr_values = new Dictionary<string, string>();
string username = string.Empty;
string error = string.Empty;
string Tester = string.Empty;
bool ok = true;
if (context.Result.ValidatedRequest.Raw != null)
{
var reqParamsDict = context.Result.ValidatedRequest.Raw.ToDictionary();
if (reqParamsDict.ContainsKey("acr_values"))
{
var raw = reqParamsDict["acr_values"].Split(' ', StringSplitOptions.RemoveEmptyEntries).ToList();
acr_values = raw.Select(item => item.Split(':', 2, StringSplitOptions.RemoveEmptyEntries)).ToDictionary(s => s[0], s => s[1]);
}
if (reqParamsDict.ContainsKey("username")) // Should always be there, name/password check would have failed already
{
username = reqParamsDict["username"];
}
else
{
ok = false;
error = "username missing from request";
}
if (ok && acr_values.ContainsKey("ExtraField")) // Could be missing
{
Tester = acr_values["ExtraField"];
}
else
{
ok = false;
error = "ExtraField missing from request";
}
if (ok)
{
if (context.Result.ValidatedRequest.Scopes.Contains("API_Name"))
{
var user = await _userManager.FindByNameAsync(username);
if (user != null)
{
if ( user.ExtraField != Tester )
{
ok = false;
error = "Failed extra test";
}
}
else
{
ok = false;
error = "User not found";
}
}
}
}
if (!ok)
{
context.Result.IsError = true;
context.Result.Error = error;
}
}
}
}
For completeness this is my Postman setup to get it working
[https://i.stack.imgur.com/BtihJ.png][1]