ASP.Net Identity Core中的AllowOnlyAlphanumericUserNames和UserValidator属性在哪里?

Sam*_*Sam 5 asp.net-identity asp.net-core-mvc

我正在尝试在我的项目中设置ASP.Net Identity Core.问题是我们将使用Windows身份验证而不是表单身份验证.通过在iisSettings的launch.settings中设置这些属性,我可以让Authorize标签在home控制器上工作:

"windowsAuthentication": true,
"anonymousAuthentication": false,
Run Code Online (Sandbox Code Playgroud)

所以现在在我的标题中,我通过我的布局文件看到我的用户名:

@User.Identity.Name
Run Code Online (Sandbox Code Playgroud)

所以我在标题右上角的用户名如下所示:

[domain\username\]
Run Code Online (Sandbox Code Playgroud)

所以现在授权标签工作.如果我关闭Windows身份验证并返回匿名身份验证,我将获得该页面的未授权状态.如果回到Windows身份验证,我可以再次看到主页/索引页面.尚未与身份有多大关系.

现在我尝试创建一个创建用户页面,最终真正成为Active Directory页面的"添加用户".所以我试图以这种格式存储UserName:

domain\username
Run Code Online (Sandbox Code Playgroud)

这是我的创建代码:

[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);
    }
Run Code Online (Sandbox Code Playgroud)

但是我收到了这条消息:

User name 'domain\username' is invalid, can only contain letters or digits.
Run Code Online (Sandbox Code Playgroud)

所以通过阅读我一直看到你可以使用UserManager的这些属性来处理这个:

AllowOnlyAlphanumericUserNames
UserValidator
Run Code Online (Sandbox Code Playgroud)

但Identity Core中似乎不存在这些属性.这是真的?如何在Core中解决此问题?非常困难.无法从默认实现中找到该属性,或者如果我尝试创建自定义用户验证器.


更新1:

我在startup.cs中注册了自定义用户验证器

services.AddTransient<IUserValidator<AppUser>, CustomUserValidator>();
Run Code Online (Sandbox Code Playgroud)

这是我的第一次尝试:

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: domain\userName.
        //    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());
    }
}
Run Code Online (Sandbox Code Playgroud)

在foreach结束时,错误计数确实是0.但是然后跳过返回并且它跳回到我的帐户控制器中的调用并且错误仍然存​​在:

IdentityResult result 
                = await _userManager.CreateAsync(user, createUserModel.Password);
Run Code Online (Sandbox Code Playgroud)

所以我的错误仍然会在模型状态中返回,如下所示:

if (result.Succeeded)
{
    return RedirectToAction("Index");
}
else
{
    foreach (IdentityError error in result.Errors)
    {
         ModelState.AddModelError("", error.Description);
     }
 }
Run Code Online (Sandbox Code Playgroud)

这是完整的创建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);
    }
Run Code Online (Sandbox Code Playgroud)

接下来,我尝试一个更简单的自定义用户验证器版本,如下所示:

public class CustomUserValidator : IUserValidator<AppUser>
{
    public Task<IdentityResult> ValidateAsync(
        UserManager<AppUser> manager, AppUser user)
    {
        return Task.FromResult(IdentityResult.Success);
    }
}
Run Code Online (Sandbox Code Playgroud)

什么都不做 只需返回强制成功.这一切都会通过但是当它返回到调用时,结果仍然是带有"InvalideCode"的IdentityResult.Failure.用户名中不能包含特殊字符.

这是踢我的屁股.没理由这个.这应该工作.为什么这非常不灵活且不可行?

这让我在使用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);
    }
Run Code Online (Sandbox Code Playgroud)

它立即开始:

IdentityResult result 
                = await _userManager.CreateAsync(user, createUserModel.Password);
Run Code Online (Sandbox Code Playgroud)

并给出500错误.

R. *_*rds 7

要更改使用名称中允许的字符,请在要传递给AddIdentity函数的选项中添加/更新此行(假设您这样做)StartUp.下面...

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;
            ...
        })
    }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助你.

UserValidator.cs

IdentityConfig.cs