2

내 사용자가 로그인하는 컨트롤러가 있습니다. 기존 사용자와 암호가 맞다고 가정하면 2fa를 사용할 수 있는지 확인합니다.RedirectToAction이 새 세션을 시작합니다.

AccountControler 로그인 방법

public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) 
    { 
     ViewData["ReturnUrl"] = returnUrl; 
     if (ModelState.IsValid) 
     { 
      // This doesn't count login failures towards account lockout 
      // To enable password failures to trigger account lockout, set lockoutOnFailure: true 
      var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, _configurationSettings.LockoutOnFailure); 
      if (result.Succeeded) 
      { 
       var user = await _userManager.FindByEmailAsync(model.Email); 
       await _signInManager.SignInAsync(user, _configurationSettings.IsPersistent); 
       _logger.LogInformation("User logged in."); 
       return RedirectToLocal(returnUrl); 
      } 
      if (result.RequiresTwoFactor) 
      { 
       return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe }); 
      } 
      if (result.IsLockedOut) 
      { 
       _logger.LogWarning("User account locked out."); 
       return RedirectToAction(nameof(Lockout)); 
      } 

      ModelState.AddModelError(string.Empty, "Invalid login attempt."); 
      return View(model); 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

사용자를 가정하면 2FA 내가 LoginWith2fa 방법로 리디렉션 다음 활성화 가지고있다.

[HttpGet] 
    [AllowAnonymous] 
    public async Task<IActionResult> LoginWith2fa(bool rememberMe, string returnUrl = null) 
    { 
     // Ensure the user has gone through the username & password screen first 
     var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); 

     if (user == null) 
     { 
      throw new ApplicationException($"Unable to load two-factor authentication user."); 
     } 

     var model = new LoginWith2faViewModel { RememberMe = rememberMe }; 
     ViewData["ReturnUrl"] = returnUrl; 

     return View(model); 
    } 

내 문제는 VAR 사용자에 오는 곳이다는 = _signInManager.GetTwoFactorAuthenticationUserAsync();는 항상 null를 돌려 기다리고 있습니다. 나는 몇 가지 중단 점을 넣었고 ApplicationSignInManager와 AccountController 모두 내 생성자를 회수하는 것처럼 보입니다. 거기에 저에게 새로운 세션을 주셨습니다. startup.cs

services.AddIdentity<ApplicationUser, IdentityRole<long>>() 
      .AddEntityFrameworkStores<ApplicationDbContext>() 
      .AddSignInManager<ApplicationSignInManager>() 
      .AddDefaultTokenProviders(); 

어떻게 RedirectToAction를 호출하고 동일한 세션을 유지합니까에서 범위로

SignInManager은 등록? 나는이 프로젝트를 Identity Server 4 Demo

업데이트를 수행 한

: 나에게 힌트를주는 @muqeetkhan 할 수있는 HttpContext에 대해 enter image description here

+2

범위 요청 [lifetime] (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection#service-lifetimes-and-registration-options)은 현재 요청에만 적용됩니다. . 'RedirectToAction'을 사용하면 브라우저에 다시 302를 보내고, 새로운 액션에 * 새로운 * 요청을함으로써 새로운 범위를 만들 수 있습니다. –

+0

'UseTwoFactorSignInCookie (...); '가 솔루션에 있습니까? – Mackan

+1

@Mackan ASP.NET Core에는 이것이 필요하지 않다고 생각합니다. –

답변

1

감사 코멘트. Becouse 나는 사용자 정의 SignInManager를 사용하여 사용자 데이터가 다음 페이지로 전파 될 수 있도록 적절한 세션 쿠키를 설정해야합니다.

public class ApplicationSignInManager : SignInManager<ApplicationUser> 
    { 

     private readonly ILogger _logger; 
     public ApplicationSignInManager(UserManager<ApplicationUser> userManager, IHttpContextAccessor contextAccessor, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory, IOptions<IdentityOptions> optionsAccessor, 
      ILogger<ApplicationSignInManager> logger, IAuthenticationSchemeProvider schemes) : base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes) 
     { 
      _logger = logger; 
     } 

     public override async Task<SignInResult> PasswordSignInAsync(string userEmail, string password, bool isPersistent, bool shouldLockout) 
     { 
      if (UserManager == null) 
       return SignInResult.Failed; 
      var result = await new FindUserCommand(_logger, UserManager, userEmail, password, shouldLockout).Execute(); 

      if (result != SignInResult.TwoFactorRequired) return result; 

      var user = await UserManager.FindByEmailAsync(userEmail); 
      return await SignInOrTwoFactorAsync(user, true); // Required sets the session Cookie 
     } 
    } 

기본적으로 SignInOrTwoFactorAsync(user, true);을 호출해야합니다.