【发布时间】:2022-01-04 15:09:50
【问题描述】:
我有用于身份验证用户的身份验证 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;
}
【问题讨论】:
-
无限循环的证据是什么?
-
嗯...无法访问此页面看起来像localhost:7216/Account/Login/…的网页......然后一些
-
刚刚添加了一些显示错误的图片
-
首先这是基于 cookie 的身份验证(不是 JWT)。第二件事,请向我们展示帐户控制器的代码。
-
添加 AccountController 和登录方法
标签: c# .net asp.net-core authentication jwt