Search code examples
asp.net-identityblazorblazor-client-side

SignIn returns successfull but User is not


I have an Blazor WASM application. I use the Identity Framework for login with:

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

The signInResult is always Succeeded.

In the StateProvider in WebAssembly I get a UserInfo object which among other things tells if the user is Authenticated:

    [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;
    }

Here User.Identity.IsAuthenticated is always false. I also checked it right after the PasswordSignInAsync but there it is the same as well.

My startup is setup this way:

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;
                                                     }
                             };
        });

And the Configure method contains:

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

AuthenticationStateProvider:

public class IdentityAuthenticationStateProvider : AuthenticationStateProvider { private UserInfoDto userInfoCache; private readonly 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));
    }
}

In general the whole process is identical to this example: https://github.com/stavroskasidis/BlazorWithIdentity (which stopped working locally as well)

What confuses me is that it worked before and still does on the server and it doesn't work locally if I checkout that history at the point deployed to the server. What do I miss?


Solution

  • okay, this is frustrating. The solution was to reboot all my computer. It seems that the issue was somewhere in IIS Express or so - on both my computer simultaneously.