Вход успешно завершен, а пользователь - нет.

У меня есть приложение Blazor WASM. Я использую Identity Framework для входа в систему с:

SignInResult signInResult = await signInManager<ApplicationUser>.PasswordSignInAsync(parameters.UserName, parameters.Password, parameters.RememberMe, true);

signInResult всегда Succeeded.

В StateProvider в WebAssembly я получаю объект UserInfo, который, помимо прочего, сообщает, аутентифицирован ли пользователь:

    [HttpGet]
    public UserInfoDto UserInfo()
    {
        return BuildUserInfo();
    }

    private UserInfoDto BuildUserInfo()
    {
        var userInfo = new UserInfoDto
        {
            IsAuthenticated = User.Identity.IsAuthenticated,
            UserName = User.Identity.Name
        };

        foreach (var claim in User.Claims)
        {
            userInfo.ExposedClaims.Add(claim.Type, claim.Value);
        }

        if (userInfo.IsAuthenticated)
        {
            userInfo.Id = Guid.Parse(identityService.GetUserId(User));
        }

        return userInfo;
    }

Здесь User.Identity.IsAuthenticated всегда ложно. Я тоже проверил это сразу после PasswordSignInAsync, но там тоже самое.

Мой запуск настроен так:

services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
        .AddEntityFrameworkStores<SupportToolContext>()
        .AddDefaultTokenProviders();

services.Configure<IdentityOptions>(options =>
        {
            // Password settings
            options.Password.RequireDigit = false;
            options.Password.RequiredLength = MIN_PASSWORD_LENGTH;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireLowercase = false;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(LOCKOUT_DURATION);
            options.Lockout.MaxFailedAccessAttempts = MAX_TRIES_BEFORE_LOCKOUT;
            options.Lockout.AllowedForNewUsers = true;

            // Email Settings
            options.User.RequireUniqueEmail = true;
            options.SignIn.RequireConfirmedEmail = true;
        });

// Configure LifeSpan of Identity email tokens
services.Configure<DataProtectionTokenProviderOptions>(options =>
        {
            options.TokenLifespan = TimeSpan.FromDays(3);
        });

services.ConfigureApplicationCookie(options =>
        {
            options.Cookie.HttpOnly = false;
            options.Events = new CookieAuthenticationEvents
                             {
                                 OnRedirectToLogin = context =>
                                                     {
                                                         context.Response.StatusCode = UNAUTHORIZED_STATUS_CODE;
                                                         return Task.CompletedTask;
                                                     }
                             };
        });

А метод Configure содержит:

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

AuthenticationStateProvider:

открытый класс IdentityAuthenticationStateProvider: AuthenticationStateProvider {частный UserInfoDto userInfoCache; закрытый только для чтения IServiceProvider serviceProvider;

    public IdentityAuthenticationStateProvider(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }

    ..

    private async Task<UserInfoDto> GetUserInfoAsync()
    {
        var authorizeApi = serviceProvider.GetRequiredService<IAuthorizeApi>();

        if (userInfoCache != null && userInfoCache.IsAuthenticated) return userInfoCache;
        userInfoCache = await authorizeApi.GetUserInfoAsync();

        return userInfoCache;
    }

    public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var identity = new ClaimsIdentity();
        try
        {
            UserInfoDto userInfo = await GetUserInfoAsync();
            if (userInfo.IsAuthenticated)
            {
                IEnumerable<Claim> claims = new[] {new Claim(ClaimTypes.Name, userInfoCache.UserName)}.Concat(
                    userInfoCache.ExposedClaims.Select(c => new Claim(c.Key, c.Value)));
                identity = new ClaimsIdentity(claims, "Server authentication");
            }
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine("Request failed:" + ex);
        }

        return new AuthenticationState(new ClaimsPrincipal(identity));
    }
}

В целом весь процесс идентичен этому примеру: https://github.com/stavroskasidis/BlazorWithIdentity (который тоже перестал работать локально)

Что меня смущает, так это то, что он работал раньше и продолжает работать на сервере, и он не работает локально, если я проверяю эту историю в точке, развернутой на сервере. Что я скучаю?


person NPadrutt    schedule 11.01.2020    source источник
comment
Вы используете User.Identity.IsAuthenticated на Blazor WebAssembly, верно? Если да, то как получить объект User и откуда?   -  person enet    schedule 11.01.2020
comment
Нет, в StateProvider в Blazor WASM я запрашиваю информацию о пользователе с сервера. В конечной точке контроллера я вызываю IsAuthenticated. Я обновил свой пост, чтобы лучше описать это.   -  person NPadrutt    schedule 11.01.2020
comment
Хорошо, @NPadrutt, я видел образец. В принципе, это похоже на то, что я предлагал. Очень сложно сказать, что не так с вашим кодом, не увидев и не протестировав все это. Возможно, вы забыли скопировать какие-то настройки, например. Убедитесь, что ваш класс Client.Startup содержит весь код из образца   -  person enet    schedule 11.01.2020
comment
Это была идея с образцом, поскольку он имеет ту же проблему, что и мой проект. И код аутентификации, насколько я могу судить, идентичен. Кроме того, я приложил все усилия, чтобы опубликовать все соответствующие части кода, но дайте мне знать, если что-то я пропустил.   -  person NPadrutt    schedule 11.01.2020


Ответы (1)


хорошо, это расстраивает. Решением было перезагрузить весь мой компьютер. Похоже, проблема была где-то в IIS Express или около того - на обоих моих компьютерах одновременно.

person NPadrutt    schedule 11.01.2020
comment
Отметьте это как ответ :) - person Michael Washington; 11.01.2020
comment
Мне нужно подождать два дня, так как это мой собственный ответ, но тогда я сделаю это :) - person NPadrutt; 11.01.2020