Приложение перенаправляет на 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?

Это запрос/ответ

enter image description here

Ответы

Ответ 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/ метод действия,