简体   繁体   中英

Claim not found after sucessful HttpContext.SigninAsync

Redefining it again.

I have a asp.net core (api) solution a.sln which has accountcontroller.cs which allows a user to login to the application. Here is AccountController.cs code having Login method.

    /// <summary>
    /// Handle postback from username/password login
    /// </summary>
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginInputModel model, string button)
    {
       if (button != "login")
        {
            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);
            if (context != null)
            {
                await _interaction.GrantConsentAsync(context, ConsentResponse.Denied);
                return Redirect(model.ReturnUrl);
            }
            else
            {
                return Redirect("~/");
            }
        }

       if (ModelState.IsValid)
        {
            var user = await _userManager.FindByNameOrEmailAsync(model.Username);

            if (user != null)
            {
                if (await _userManager.CheckPasswordAsync(user, model.Password) && !await _userManager.IsEmailConfirmedAsync(user))
                {
                    ModelState.AddModelError("", Messages.UserEmailUnverified(_httpContextAccessor));
                }
                else if (await _userManager.CheckPasswordAsync(user, model.Password) && !(await _userManager.IsLockedOutAsync(user)))
                {
                    var userRoles = await _userManager.GetRolesAsync(user);
                    var userClaims = userRoles.Select(x => new Claim(ClaimTypes.Role, x)).ToList();

                    await _events.RaiseAsync(
                        new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName));

                    var rememberMe = _accountOptions.AllowRememberLogin && model.RememberLogin;

                    var props = new AuthenticationProperties()
                    {
                        IsPersistent = rememberMe,
                        ExpiresUtc = DateTimeOffset.UtcNow.Add(rememberMe ? TimeSpan.FromDays(_accountOptions.RememberMeLoginDurationDays)
                                        : TimeSpan.FromMinutes(_accountOptions.StandardLoginDurationMinutes))
                    };

                    userClaims.Add(new Claim("remember_me", model.RememberLogin.ToString()));

                    var appIdentity = new ClaimsIdentity(userClaims, CookieAuthenticationDefaults.AuthenticationScheme);
                    HttpContext.User.AddIdentity(appIdentity);

                    await HttpContext.SignInAsync(user.Id, user.UserName, props, userClaims.ToArray());

                    //after successful login reset lockout count
                    await _userManager.ResetAccessFailedCountAsync(user);

                    bool isAllowedUrl = !_middlewareConf.ClientRedirectUrls.Where(urlToCheck => model.ReturnUrl.Contains(urlToCheck)).IsNullOrEmpty();

                    if (_interaction.IsValidReturnUrl(model.ReturnUrl) || isAllowedUrl)
                    {
                        return Redirect(model.ReturnUrl);
                    }

                    return Redirect(_loginConfiguration.DefaultRedirectUrl);
                }
                else
                {
                    var error = await _accountManager.HandleLockout(user);
                    ModelState.AddModelError("", error);
                }
            }
            else
            {
                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, $"Invalid credentials."));
                ModelState.AddModelError("", _accountOptions.InvalidCredentialsErrorMessage);
            }
        }

        var vm = await _account.BuildLoginViewModelAsync(model);
        return View(vm);
    }

In above Login method, we are explicitly adding Claim "remember_me".

After successful login, i am directed to another asp.net core solution where on start.cs i am trying to find that same claim. Here is the code of start.cs.

  public void Configuration(IAppBuilder app)
    {
        var idConfig = IdentityConfiguration.Configuration;
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        app.UseKentorOwinCookieSaver();

        //tell app to use Cookies as the default
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        // Use cookie authentication
        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        {
            AuthenticationType = "Cookies",
            ExpireTimeSpan = TimeSpan.FromMinutes(idConfig.CookieExpiresMinutes ?? 60),
            SlidingExpiration = idConfig.CookieSlidingExpiration ?? false,
            Provider = new CookieAuthenticationProvider
            {
                OnResponseSignIn = signInContext =>
                {
                    var rememberMeClaim = signInContext.Identity.Claims.FirstOrDefault(c => c.Type == "remember_me");

                    if (bool.TryParse(rememberMeClaim?.Value, out var rememberMe))
                    {
                        if (rememberMe && idConfig.RememberCookieExpiresDays.HasValue)
                        {
                            signInContext.CookieOptions.Expires = DateTime.Now.AddDays(idConfig.RememberCookieExpiresDays.Value);
                        }
                    }
                }
            }
        });
   }

But in above code, i am not able to find the same claim "remember_me".

Am i missing something ?

Instead of adding claims like :-

userClaims.Add(new Claim("remember_me", model.RememberLogin.ToString()));

Add claim like below :-

 await _userManager.AddClaimAsync(user, new Claim("remember_me",model.RememberLogin.ToString()));

Now, i am able to get my claim "remember_me".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM