添加身份验证时出现无限循环

Getting infinite loop when adding Authentication

我有认证用户的认证 API (jwt)。将其用于多个客户,现在正在添加第二个客户。第一个可以正常工作。 我确定问题出在这部分:

var _authorizePolicy = new AuthorizationPolicyBuilder()
                  .RequireAuthenticatedUser()
                  .Build();

var _serviceProvider = builder.Services.BuildServiceProvider();

var _authenticationSettings = _serviceProvider.GetService<IAuthenticationSettings>();

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                      .AddCookie(JwtBearerDefaults.AuthenticationScheme,
                        options => {
                            options.LoginPath = _authenticationSettings.LoginPath;
                            options.AccessDeniedPath = _authenticationSettings.AccessDeniedPath;
                            options.Events = new CookieAuthenticationEvents
                            {
                                // Check if JWT needs refreshment 
                                OnValidatePrincipal = RefreshTokenMonitor.ValidateAsync
                            };
                            options.Cookie.Name = "MainAppCookie";
                        }
                      );

builder.Services.AddMvc(config => 
    { 
        config.Filters.Add(new AuthorizeFilter(_authorizePolicy)); 
    })
   .AddNewtonsoftJson(options => 
    {
       options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
    })
   .AddViewOptions(options => options.HtmlHelperOptions.ClientValidationEnabled = true);

我有相同的代码(Cookie 的不同名称)是第一个应用程序,在那里工作正常。

这里有 AccountController:

public class AccountController : Controller

{ 私人只读 ISecurityManager _securityManager;

public AccountController(ISecurityManager securityManager)
{
    _securityManager = securityManager;
}

public async Task<IActionResult> Login()
{
    return View(new LoginViewModel());
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login([FromForm] LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;

    if (!ModelState.IsValid)
    {
        ViewBag.ErrorMessage = "Input data incorrect. Please try again";
        ModelState.AddModelError(string.Empty, "Invalid login form");
        return View(model);
    }

    if (await _securityManager.LoginUser(model.Email, model.Password))
        return RedirectToLocal(returnUrl);
    else
    {
        ViewBag.ErrorMessage = "Invalid login attempt.";
        return View(model);
    }
    return View(model);
}

public async Task<IActionResult> AccessDenied()
{
    return View();
}

[HttpGet]
[Route("account/password/forgot")]
public async Task<IActionResult> ForgotPassword()
{
    return View(new ForgotPasswordModel());
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPasswordSubmit(ForgotPasswordModel model)
{
    return RedirectToAction(nameof(ForgotPasswordConfirmation));
}

[Route("account/password/confirmation")]
public async Task<IActionResult> ForgotPasswordConfirmation()
{
    return View();
}

[HttpGet]
[Route("account/password/reset")]
public async Task<IActionResult> ResetPassword()

{
    return View(new PasswordResetModel());
}

[HttpPost]
public async Task<IActionResult> ResetPasswordSubmit(PasswordResetModel model)
{
    return RedirectToAction(nameof(Login), new { });
}

public async Task<IActionResult> LogOut()
{
    //await _securityManager.LogOut();
    return RedirectToAction(nameof(Login));
}

// Prevent session stealing
private IActionResult RedirectToLocal(string returnUrl)
{
    if (Url.IsLocalUrl(returnUrl))
        return Redirect(returnUrl);
    else
        return RedirectToAction(nameof(HomeController.Index), "Home");
}

}

这里是您的实际登录名:

 private async Task<bool> Login(AuthResult token)
{
    if(token.Token.IsNullOrEmpty())
        return false;

    await LogOut();

    var _tokenHandler = new JwtSecurityTokenHandler();
    var _tokenSettings = _jwtTokenValidationSettings.CreateTokenValidationParameters();
    var _principal = _tokenHandler.ValidateToken(token.Token, _tokenSettings, out var _validatedToken);
    var _identity = _principal.Identity as ClaimsIdentity;
    var _securityToken = _tokenHandler.ReadToken(token.Token) as JwtSecurityToken;
    var _extraClaims = _securityToken.Claims.Where(c => !_identity.Claims.Any(x => x.Type == c.Type)).ToList();

    _extraClaims.Add(new Claim("jwt", token.Token));
    _extraClaims.Add(new Claim("refreshToken", token.RefreshToken));
    _identity.AddClaims(_extraClaims);

    var _authenticationProperties = new AuthenticationProperties()
    {
        IssuedUtc = _identity.Claims.First(c => c.Type == JwtRegisteredClaimNames.Iat)?.Value.ToInt64().ToUnixEpochDate(),
        ExpiresUtc = _identity.Claims.First(c => c.Type == JwtRegisteredClaimNames.Exp)?.Value.ToInt64().ToUnixEpochDate(),
        IsPersistent = true
    };

    await _httpContext.SignInAsync(JwtBearerDefaults.AuthenticationScheme, _principal, _authenticationProperties);
    

    return _identity.IsAuthenticated;
}

并进一步澄清...这是我得到的错误:

您的 LoginControler(或其多个操作)需要 [AllowAnonymous] 才能绕过身份验证检查。否则,用户将无权查看这些路线。

错误实际上是在 AccountController 的 [AllowAnonymous] 属性中。 删除它并构建项目,再次添加属性。很有魅力:)