我正在尝试在我的项目中设置 ASP.Net 身份核心。 问题是我们将使用Windows身份验证而不是表单身份验证。 我能够通过在 launch.settings 中设置这些属性来获取授权标签以在主控制器上工作。
"windowsAuthentication": true,
"anonymousAuthentication": false,
所以现在在我的标题中,我使用这个通过我的布局文件看到我的用户名:
@User.Identity.Name
所以我在标题右上角的用户名看起来像这样:
[domainusername]
所以现在授权标签可以工作了。 如果我关闭 Windows 身份验证并返回到匿名身份验证,我将获得页面的未授权状态。 如果回到Windows身份验证,我可以再次看到主页/索引页面。 与身份还没有太大关系。
现在我尝试制作一个创建用户页面,最终将真正成为活动目录页面的"添加用户"。 所以我正在尝试以这种格式存储用户名:
domainusername
这是我的创建代码:
[HttpPost]
public async Task<IActionResult> CreateUser(CreateUserViewModel createUserModel)
{
if (ModelState.IsValid)
{
AppUser user = new AppUser
{
UserName = createUserModel.Name,
Email = createUserModel.Email
};
IdentityResult result
= await _userManager.CreateAsync(user, createUserModel.Password);
if (result.Succeeded)
{
return RedirectToAction("Index");
}
else
{
foreach (IdentityError error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
return View(createUserModel);
}
但是我得到这条消息:
User name 'domainusername' is invalid, can only contain letters or digits.
因此,通过阅读,我一直看到您可以使用UserManager中的这些属性来处理此问题:
AllowOnlyAlphanumericUserNames
UserValidator
但这些属性似乎在标识核心中不存在。 这是真的吗? 如何在 Core 中解决此问题? 很卡住。 无法从默认实现中找到该属性,或者如果我尝试创建自定义用户验证程序。
更新 1:
我在启动时注册了自定义用户验证程序.cs
services.AddTransient<IUserValidator<AppUser>, CustomUserValidator>();
这是我的第一次尝试:
public class CustomUserValidator : UserValidator<AppUser>
{
public async override Task<IdentityResult> ValidateAsync(
UserManager<AppUser> manager, AppUser user)
{
IdentityResult result = await base.ValidateAsync(manager, user);
// Allow '' char for active directory userNames: domainuserName.
// Default does not allow special chars.
foreach (IdentityError error in result.Errors)
{
if (error.Code == "InvalidUserName")
{
((List<IdentityError>)result.Errors).Remove(error);
}
}
return result.Errors.Count() == 0 ? IdentityResult.Success
: IdentityResult.Failed(result.Errors.ToArray());
}
}
在 foreach 结束时,错误计数确实为 0。 但是随后返回被跳过,它跳回到我的帐户控制器中的调用,错误仍然存在:
IdentityResult result
= await _userManager.CreateAsync(user, createUserModel.Password);
所以我的错误仍然在模型状态下返回,如下所示:
if (result.Succeeded)
{
return RedirectToAction("Index");
}
else
{
foreach (IdentityError error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
以下是完整的创建 POST:
[HttpPost]
public async Task<IActionResult> CreateUser(CreateUserViewModel createUserModel)
{
if (ModelState.IsValid)
{
AppUser user = new AppUser
{
UserName = createUserModel.Name,
Email = createUserModel.Email
};
IdentityResult result
= await _userManager.CreateAsync(user, createUserModel.Password);
if (result.Succeeded)
{
return RedirectToAction("Index");
}
else
{
foreach (IdentityError error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
return View(createUserModel);
}
接下来,我尝试一个更简单版本的自定义用户验证器,如下所示:
public class CustomUserValidator : IUserValidator<AppUser>
{
public Task<IdentityResult> ValidateAsync(
UserManager<AppUser> manager, AppUser user)
{
return Task.FromResult(IdentityResult.Success);
}
}
什么都不要做。 只需返回强制成功。 这一切都会通过,但是当它返回到调用时,结果仍然是 IdentityResult.失败与"无效代码" 用户名中不能有特殊字符。
这是在踢我的屁股。 没有理由。 这应该有效。 为什么这如此难以置信地僵化和不可行?
这让我在使用 Core 的工作中看起来非常愚蠢,我可能会因为这个 fbs 而被解雇。
更新 2:
我尝试将其正确放入控制器中,但它仍然不起作用。
[HttpPost]
public async Task<IActionResult> CreateUser(CreateUserViewModel createUserModel)
{
if (ModelState.IsValid)
{
AppUser user = new AppUser
{
UserName = createUserModel.Name,
Email = createUserModel.Email
};
IdentityResult result
= await _userManager.CreateAsync(user, createUserModel.Password);
foreach (IdentityError error in result.Errors)
{
if (error.Code == "InvalidUserName")
{
((List<IdentityError>)result.Errors).Remove(error);
}
}
if (result.Errors.Count() == 0)
{
result = IdentityResult.Success;
}
if (result.Succeeded)
{
return RedirectToAction("Index");
}
else
{
foreach (IdentityError error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
return View(createUserModel);
}
它紧接着踢出:
IdentityResult result
= await _userManager.CreateAsync(user, createUserModel.Password);
并给出 500 错误。
要更改使用名称中允许的字符,请在传递给StartUp
类中AddIdentity
函数的选项中添加/更新此行(假设您这样做)。 下面...
options.User.AllowedUserNameCharacters = "";
或
options.User.AllowedUserNameCharacters = null;
如果要跳过对用户名的验证,请将其设置为空字符串或null
。
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
...
services.AddIdentity<YourUser, YourRole>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.User.AllowedUserNameCharacters = null; // HERE!
options.User.RequireUniqueEmail = true;
...
})
}
希望这对您有所帮助。
用户验证器.cs
身份配置.cs