【问题标题】:App redirects to Account/AccessDenied on adding Oauth应用程序在添加 Oauth 时重定向到 Account/AccessDenied
【发布时间】:2016-12-09 15:36:17
【问题描述】:

我偶然发现了一个问题,即在向当前登录的用户添加社交媒体身份验证时,应用程序不一致地将用户重定向到 Account/AccessDenied/。它似乎在用户第一次登录时起作用,然后通过尝试添加另一种身份验证方法,它将用户返回到Account/AccessDenied?ReturnUrl=%2Fmanage%2Flinklogincallback

我的猜测是 [Authorize] 属性出了点问题,但只是我第二次尝试添加外部身份验证方法。

管理控制器

[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的排列顺序?

这是请求/响应

【问题讨论】:

  • 此错误是否持续发生?因为当我的代码仍然抛出错误异常时,我经常遇到这个错误。清除 cookie 暂时解决了这个问题。后来当我修复了我的小错误时,不再发生这种重定向。
  • 它始终如一地发生,但我不知道它是什么,因为其他一切都按预期工作。您修复了哪些小错误以使其正常工作?
  • 您是否在Startup 类的Configure() 方法中添加了app.UseGoogleAuthentication(...)
  • 我的错误是在 OAuth 挑战之后但在将 Faceboook 登录与用户关联之前抛出了一些异常。所以我最终得到了带有不存在用户声明的浏览器 cookie。清除 cookie 和 DELETE FROM USERS 表就可以了。尝试这样做,重置您的数据库和 cookie。
  • 我还以用户(而不是开发人员)的身份访问了 Facebook,并从我的个人资料中删除了该应用程序并再次尝试。不确定 Google 是否可以做到这一点。

标签: c# asp.net-mvc asp.net-core .net-core


【解决方案1】:

@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 年 5 月)中,cookie 具有前缀“.AspNetCore.”。所以cookie名称应该是“.AspNetCore.Identity.External

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题。我正在使用来自 here 的 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"
            });
    

    我必须从应用程序使用的当前身份系统的 cookie 选项中获取用于识别外部身份验证 cookie 的方案,而不是仅使用来自 IdentityServerConstants.ExternalAUthenticationScheme 的常量“外部”。这就是为我解决问题的原因。

    【讨论】:

    • 感谢您的信息,很高兴知道我现在正在实施 IDS4 :)
    【解决方案3】:

    我已经得到了负责安全 repo 的 aspnet 团队的确认,这是一个错误(请参阅issue)并在下一个版本之前解决。 临时解决方法是设置一个名为

    的 cookie

    身份.外部

    为空,这是在向您的帐户添加外部登录时创建的。

    if (Request.Cookies["Identity.External"] != null)
    {
         Response.Cookies.Delete("Identity.External"); 
    }
    

    【讨论】:

    • 你能把github问题的链接发上来吗?
    • 用链接更新答案,@GerardoGrignoli
    • 我也遇到了这个问题,但是在我升级到 1.1.0 之后,即使没有解决方法也可以正常工作
    【解决方案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】:

      如果您在Startup.cs 中设置了config.SignIn.RequireConfirmedEmail = true,并且外部验证用户(例如Facebook 登录)的EmailConfirmed 字段为false,那么在后续登录时,您将被定向到Account/AccessDenied/动作方法。

      【讨论】:

      • 我已将EmailConfirmed 设置为true,因为它对外部登录有意义并且没有帮助
      猜你喜欢
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多