Это метод обратного вызова:
[AllowAnonymous]
[HttpGet("ExternalLoginCallback")]
public async Task ExternalLoginCallback(string? returnUrl = null, string? remoteError = null)
{
returnUrl ??= Url.Content("~/");
LoginViewModel loginViewModel = new ()
{
ReturnUrl = returnUrl,
ExternalLogins = (await signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
};
if (remoteError != null)
{
ModelState
.AddModelError(string.Empty, $"Error desde el proveedor externo: {remoteError}");
loginViewModel.SetError(remoteError);
return View("Login", loginViewModel);
}
// Get the login information about the user from the external login provider
var info = await signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ModelState
.AddModelError(string.Empty, "Error al cargar la información del login externo.");
loginViewModel.SetError("Error al cargar la información del login externo.");
return View("Login", loginViewModel);
}
// If the user already has a login (i.e if there is a record in AspNetUserLogins
// table) then sign-in the user with this external login provider
var signInResult = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
var userName = info.Principal.FindFirstValue(ClaimTypes.Email);
if (signInResult.Succeeded)
{
if (userName != null)
{
await SetLastLoggedOnTime(userName);
var user = await userManager.FindByNameAsync(userName);
if (user != null)
await userManager.UpdateSecurityStampAsync(user);
}
return LocalRedirect(returnUrl);
}
else
{
// Verifica que el usuario exista. Si existe, agrega el login y autentica
var creado = userName == null ? null : await usuarioService.CreateUserFromExternal(userName, info);
if (creado != null)
{
await userManager.AddLoginAsync(creado, info);
await signInManager.SignInAsync(creado, isPersistent: false);
if (userName != null)
await SetLastLoggedOnTime(userName);
return LocalRedirect(returnUrl);
}
else
{
loginViewModel.Notification = new Integration.ViewModels.MessageViewModel
{
Type = Integration.ViewModels.AlertTypes.Danger
};
if (signInResult.IsLockedOut)
loginViewModel.SetError("El usuario está bloqueado.");
else if (signInResult.IsNotAllowed)
loginViewModel.SetError("El usuario no está autorizado para ingresar.");
else
loginViewModel.SetError("El usuario no está registrado en la plataforma.");
}
}
return View("Login", loginViewModel);
}
Когда пользователь входит в систему, LocalRedirect(returnUrl) перенаправляет на защищенную страницу. Эта целевая страница считает, что пользователь не аутентифицирован (IsAuthenticatedСвойство имеет значение false), поэтому система перенаправляет обратно на страницу входа. Если я сразу установлю URL-адрес браузера на защищенную страницу, не пытаясь снова войти в систему, IsAuthenticated станет истинным, и страница отобразится.
Что здесь не так?
Что здесь не так? p>
Обратите внимание, что когда я вижу объект info после внешней аутентификации, IsAuthenticated отображается как true.

А также User.Identity.IsAuthenticated:

Только при выполнении перенаправления тот целевая страница имеет User.Identity.IsAuthenticated = false
У меня есть этот код в пользовательском атрибуте AuthorizeAttribute. На этом этапе я вижу, что свойство неверно:

Как я уже сказал, если я изменю URL-адрес браузера на защищенную страницу, результат будет следующий:

Наконец, вот как я настраиваю аутентификацию.
var ab = services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = true;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = configuration["Modules:Authenticate:AuthJwt:Issuer"],
ValidateAudience = true,
ValidAudience = configuration["Modules:Authenticate:AuthJwt:Audience"],
ValidateIssuerSigningKey = true,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Modules:Authenticate:AuthJwt:Key"] ?? string.Empty))
};
});
string googleClientId = configuration["Modules:Authenticate:Google:ClientId"] ?? string.Empty;
if (googleClientId != string.Empty)
ab.AddGoogle(googleOptions =>
{
googleOptions.ClientId = googleClientId;
googleOptions.ClientSecret = configuration["Modules:Authenticate:Google:ClientSecret"] ?? string.Empty;
googleOptions.CallbackPath = "/Security/GoogleSignIn";
});
string facebookAppId = configuration["Modules:Authenticate:Facebook:AppId"] ?? string.Empty;
if (facebookAppId != string.Empty)
ab.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = configuration["Modules:Authenticate:Facebook:AppId"] ?? string.Empty;
facebookOptions.AppSecret = configuration["Modules:Authenticate:Facebook:AppSecret"] ?? string.Empty;
facebookOptions.CallbackPath = "/Security/FacebookSignIn";
});
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "MyCore";
options.Cookie.Path = "/";
options.LoginPath = "/Authenticate/Security/Login";
options.LogoutPath = "/Authenticate/Security/Logout";
options.AccessDeniedPath = "/Authenticate/Security/AccessDenied";
options.ReturnUrlParameter = "ReturnUrl";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.SlidingExpiration = true;
options.Cookie.SameSite = SameSiteMode.Strict;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = (context) =>
{
// Hice esto para que no considere el módulo en el que se encuentra el usuario
Uri oldUri = new(context.RedirectUri, UriKind.RelativeOrAbsolute);
Uri newUri = new($"{options.LoginPath}{oldUri.Query}", UriKind.Relative);
context.HttpContext.Response.Redirect(newUri.ToString());
return Task.CompletedTask;
}
};
});
Подробнее здесь: https://stackoverflow.com/questions/792 ... s-i-refres
Мобильная версия