Blazor + MongoDb Identity: значение не может быть нулевым. (Имя параметра «источник») - PullRequest
0 голосов
/ 20 апреля 2020

Не могли бы вы помочь мне. Я пытаюсь использовать Blazor с MongoDb Identity и всегда получаю исключение: значение не может быть нулевым. (Имя параметра 'source'), когда я вызываю signInManager.SignInAsyn c (user, false);

Версия сервера MongoDB: 4.2.5

ASP. Net Core 3.1

Пакеты NuGet: AspNetCore.Identity.Mon go: 6.7.0 MongoDB.Driver: 2.10.3

Предварительные шаги: 1. Создайте простой проект Blazor Server без аутентификации. 2. Затем я просто добавляю AspNetCore.Identity.Mon go.

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.Configure<BookstoreDatabaseSettings>(Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
             sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);

        services
            .AddIdentityMongoDbProvider<ApplicationUser, ApplicationRole>(identityOptions =>
            {
                identityOptions.Password.RequiredLength = 1;
                identityOptions.Password.RequireLowercase = false;
                identityOptions.Password.RequireUppercase = false;
                identityOptions.Password.RequireNonAlphanumeric = false;
                identityOptions.Password.RequireDigit = false;
            }, mongoIdentityOptions =>
            {
                mongoIdentityOptions.ConnectionString = Configuration.GetConnectionString("MongoDbDatabase");
            })
            .AddDefaultTokenProviders();

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        });

        services.AddRazorPages();
        services.AddServerSideBlazor();
        services.AddSingleton<WeatherForecastService>();

        services.AddScoped<BookService>();
        services.AddTransient<LoginService>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
        });
    }
}

ApplicationUser.cs

public class ApplicationUser : MongoUser
{
    public string Name { get; set; }
    public string LastName { get; set; }
    public string Gender { get; set; }
    public DateTime? Birthdate { get; set; }
    public string Country { get; set; }
    public string State { get; set; }
    public string City { get; set; }
}

ApplicationRole.cs

public class ApplicationRole : MongoRole
{
}

RegisterNewUserData.cs

public class RegisterUserData
{
    public string UserName { get; set; }
    public string Gender { get; set; }
    public string Password { get; set; }
    public string ConfirmedPassword { get; set; }
}

LoginService.cs

public class LoginService
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly IConfiguration _configuration;
    private readonly RoleManager<ApplicationRole> _roleManager;

    public LoginService(UserManager<ApplicationUser> userManager,
                                 SignInManager<ApplicationUser> signInManager,
                                 IConfiguration configuration,
                                 RoleManager<ApplicationRole> roleManager)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _configuration = configuration;
        _roleManager = roleManager;
    }

    public async Task<bool> LogIn(LoginUserData loginUser)
    {
        ApplicationUser user = await _userManager.FindByNameAsync(loginUser.UserName);

        if (user != null)
        {
            try
            {  
                var result2 = await _signInManager.PasswordSignInAsync(user.Email, loginUser.Password, loginUser.RememberMe, lockoutOnFailure: true);
                if (result2.Succeeded)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
        return false;
    }

    public async Task<bool> RegisterNewUser(RegisterUserData regUser)
    {
        string roleName = "Member";
        var user = new ApplicationUser
        {
            Name = regUser.UserName,
            UserName = regUser.UserName,
            Email = regUser.UserName,
            Gender = regUser.Gender,
            LastName = "",
            Country = "",
            State = "",
            City = ""
        };

        bool isRoleExists = await _roleManager.RoleExistsAsync(roleName);
        if (isRoleExists == false)
        {
            var role = new ApplicationRole();
            role.Name = roleName;
            await _roleManager.CreateAsync(role);
        }

        var result = await _userManager.CreateAsync(user, regUser.Password);
        if (result.Succeeded)
        {
            await _userManager.AddToRoleAsync(user, roleName);

            var claims = new List<Claim>
            {
                new Claim("user", user.UserName),
                new Claim("role", roleName)
            };
            result = await _userManager.AddClaimsAsync(user, claims);

            if (result.Succeeded)
            {
                try
                {
                    await _signInManager.SignInAsync(user, false);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    throw;
                }                    
                return true;
            }
        }
        return false;
    }
}

В процессе регистрации Пользователь, Роли и Требования созданы и успешно добавлены. Вот данные из MongoDb:

{
  "_id": {
    "$oid": "5e9df2819fecf83484901211"
  },
  "UserName": "M1@g.com",
  "NormalizedUserName": "M1@G.COM",
  "Email": "M1@g.com",
  "NormalizedEmail": "M1@G.COM",
  "EmailConfirmed": false,
  "PasswordHash": "AQAAAAEAACcQAAAAEGdbk1EC4niPacknWuMDpbc+YRZP5CmvH0IaUIslo5/vcHplpJO/iWBU/6opCYsErQ==",
  "SecurityStamp": "BOYJUYQFPMLMHJ6NFBHG64K4SC7WEF5W",
  "ConcurrencyStamp": "e9133395-1eed-4757-91a5-a5fc1d699f5d",
  "PhoneNumber": null,
  "PhoneNumberConfirmed": false,
  "TwoFactorEnabled": false,
  "LockoutEnd": null,
  "LockoutEnabled": true,
  "AccessFailedCount": 0,
  "AuthenticatorKey": null,
  "Roles": [
    "5e9df27c9fecf83484901210"
  ],
  "Claims": [
    {
      "_id": 0,
      "UserId": null,
      "ClaimType": "user",
      "ClaimValue": "M1@g.com"
    },
    {
      "_id": 0,
      "UserId": null,
      "ClaimType": "role",
      "ClaimValue": "Member"
    }
  ],
  "Logins": [],
  "Tokens": [],
  "RecoveryCodes": [],
  "Name": "M1@g.com",
  "LastName": "",
  "Gender": "Male",
  "Birthdate": null,
  "Country": "",
  "State": "",
  "City": ""
}

Но когда процесс вызывает:

_signInManager.SignInAsync(user, false);

или:

await _signInManager.PasswordSignInAsync(user.Email, loginUser.Password, loginUser.RememberMe, lockoutOnFailure: true);

Я получил исключение: Значение не может быть нулевым (Имя параметра «источник») . Итак, что я пропустил?

Примечания, я использую то же решение с ASP. Net Core 2.1 + Razor Pages + MongoDb Identity, и это хорошо работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...