Приложение перенаправляет на Account/AccessDenied при добавлении Oauth
Я наткнулся на проблему, когда непоследовательно приложение перенаправляет пользователя на Account/AccessDenied/
при добавлении аутентификации в социальные сети к текущему зарегистрированному пользователю. Кажется, что он работает при первом Account/AccessDenied?ReturnUrl=%2Fmanage%2Flinklogincallback
пользователя в систему, а затем, добавив еще один метод проверки подлинности, возвращает пользователя в Account/AccessDenied?ReturnUrl=%2Fmanage%2Flinklogincallback
.
Я предполагаю, что что-то идет не так с атрибутом [Authorize], но только во второй раз я пытаюсь добавить внешний метод проверки подлинности.
ManageController
[Authorize]
public class ManageController : Controller
{
//
// POST: /Manage/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
return Challenge(properties, provider);
}
//
// GET: /Manage/LinkLoginCallback
[HttpGet]
public async Task<ActionResult> LinkLoginCallback()
{
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
if (info == null)
{
return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
}
var result = await _userManager.AddLoginAsync(user, info);
var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
}
Может быть, порядок расположения startup.cs?
Это запрос/ответ
Ответы
Ответ 1
Я подтвердил, что команда aspnet работает над репо безопасности, что это ошибка (см. Эту проблему) и разрешена до следующего выпуска. Временным решением является установка файла cookie с именем
Identity.External
null, который создается при добавлении внешнего входа в вашу учетную запись.
if (Request.Cookies["Identity.External"] != null)
{
Response.Cookies.Delete("Identity.External");
}
Ответ 2
Обходное решение @Rovdjuret помогло мне, пока оно не разрешилось командой asp.net. Вот мой контроллер Действие входа:
public IActionResult Login(string returnUrl = null)
{
if (_signInManager.IsSignedIn(User))
{
// redirect to user profile page
return RedirectToAction(nameof(HomeFileController.Index), "HomeFile");
}
else
{
// clear Identity.External cookie
if (Request.Cookies["Identity.External"] != null)
{
Response.Cookies.Delete("Identity.External");
}
return View(new LoginViewModel{ ReturnUrl = returnUrl, RememberMe = true });
}
}
Обновление: в последней версии (по состоянию на май 2017 года) файлы cookie имеют префикс ".AspNetCore". Таким образом, имя файла cookie должно быть " .AspNetCore.Identity.External "
Ответ 3
Я тоже столкнулся с той же проблемой. Я использовал код из примера IdentityServer4 QuickStart отсюда
app.UseGoogleAuthentication(new GoogleOptions
{
AuthenticationScheme = "Google",
DisplayName = "Google",
SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme,
ClientId = "xxx.apps.googleusercontent.com",
ClientSecret = "xxxx-Xxxxxxx"
});
Мне пришлось изменить код на следующий, чтобы исправить проблему.
var CookieScheme= app.ApplicationServices.GetRequiredService<IOptions<IdentityOptions>>().Value.Cookies.ExternalCookieAuthenticationScheme;
app.UseGoogleAuthentication(new GoogleOptions
{
AuthenticationScheme = "Google",
DisplayName = "Google",
SignInScheme = CookieScheme,
ClientId = "xxx.apps.googleusercontent.com",
ClientSecret = "xxxx-Xxxxxxx"
});
Вместо того, чтобы просто использовать константу 'external' из IdentityServerConstants.ExternalAUthenticationScheme
мне пришлось получить схему, используемую для идентификации внешних файлов cookie проверки подлинности из параметров cookie текущей системы идентификации, используемой приложением. Именно это и решило проблему для меня.
Ответ 4
обходной способ помог мне, пока его не решила команда asp.net
// GET: /Account/AccessDenied
[HttpGet]
[AllowAnonymous]
public IActionResult AccessDenied(string returnUrl = null)
{
// workaround
if (Request.Cookies["Identity.External"] != null)
{
return RedirectToAction(nameof(ExternalLoginCallback), returnUrl);
}
return RedirectToAction(nameof(Login));
}
Ответ 5
Если вы установили config.SignIn.RequireConfirmedEmail = true
в Startup.cs
и EmailConfirmed
поля false
для внешней проверки подлинности пользователя (например, Facebook входа в системе), на последующих регистрациях, вы будете перенаправлены на Account/AccessDenied/
метод действия,