【问题标题】:Why does OAuth fail when using ASP.NET Identity Core?为什么使用 ASP.NET Identity Core 时 OAuth 会失败?
【发布时间】:2019-03-18 23:24:07
【问题描述】:

我有一个具有以下配置的 ASP.NET Core 2.x 项目:

services
  .AddAuthentication(options => options.DefaultScheme = CookieAuthenticaitonDefaults.AuthenticationScheme)
  .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddFacebook(ConfigureFacebook);

可以预见的是,当我从我的一项操作中调用时:

return Challenge(new AuthenticationProperties { RedirectUri = "/test" }, "Facebook");

... 然后,我浏览了 Facebook OAuth 序列。当我找到返回应用程序的方法时,HttpContext.User.Identity 会填充相关详细信息:

  • User.Identity.Name - Facebook 用户名。
  • User.Identity.AuthenticationType - 字符串"Facebook"
  • User.Identity.IsAuthenticated - true

这一切都很好,正如预期的那样。但是,如果我将以下内容添加到我的应用程序配置中

services.AddIdentity<MyUserType, MyRoleType>()
  .AddEntityFrameworkStores<MyDbContext>();

突然之间,OAuth 流程以 User.Identity 匿名结束,没有其他任何更改。如果我们深入研究 IdentityServiceCollectionExtensions.cs,我们会发现:

options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme; options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme; options.DefaultSignInScheme = IdentityConstants.ExternalScheme;

除此之外......

这里发生了什么?为什么 Identity 会干扰 Cookie 过程,以及从 OAuth 提供者返回用户的正确方法是什么?

【问题讨论】:

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


    【解决方案1】:

    要结合 OAuth 和 Asp.Net Core Identity,您需要配置 facebookOptions.SignInSchemeCookieAuthenticationDefaults.AuthenticationScheme

    试试下面的代码:

    services
        .AddAuthentication(options => options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddFacebook(facebookOptions =>
        {
            facebookOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            facebookOptions.AppId = "xx";
            facebookOptions.AppSecret = "xxx";
        });
    

    【讨论】:

    • 不幸的是,这不起作用。从 Facebook(或其他提供商)返回时,User.Identity 是匿名的。
    • 补充我的其他评论,FacebookOptions.SignInScheme 回退到 AuthenticationOptions.DefaultSignInScheme 和 AuthenticationOptions.DefaultScheme,因此添加该行是无关紧要的。
    【解决方案2】:

    在结合 ASP.NET Identity 和 OAuth 时,需要考虑一些因素:

    配置服务:

    不再需要添加 AddCookie(CookieAuthenticationDefaults.AuthenticationScheme),因为 Identity 添加了自己的 cookie 处理程序。

    将外部用户作为 ClaimsPrincipal:

    如果您希望在HttpContext.User 下填充外部用户,请执行以下操作:

    .AddFacebook(options => {
        options.SignInScheme = IdentityConstants.ApplicationScheme;
    })
    

    在被重定向到挑战的AuthenticationProperties 中的RedirectUri 后,您的HttpContext.User 将被填充。

    获取外部用户为ExternalLoginInfo:

    如果您需要了解有关用户的信息,例如:

    1. 他们来自哪个提供商?
    2. 他们在提供程序上的唯一密钥是什么?

    你的服务应该这样配置:

    services.AddAuthentication()
        .AddFacebook(options =>
        {
            options.AppId = "";
            options.AppSecret = "";
        });
    
    services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<MyDbContext>();
    

    在您的登录控制器中,将SignInManager&lt;TUser&gt; 注入:

    public DefaultController(SIgnInManager<IdentityUser> signInManager)
    

    在您的挑战动作中,使用ConfigureExternalAuthenticationProperties 获取挑战属性:

    public IActionResult LoginExternal() {
        var props = SignInManager.ConfigureExternalAuthenticationProperties("Facebook", "/");
        return Challenge(props, "Facebook");
    }
    

    在您的返回操作中,使用GetExternalLoginInfoAsync 获取有关用户的外部详细信息:

    public async Task<IActionResult> LoginCallback() {
        var loginInfo = await SignInManager.GetExternalLoginInfoAsync();
        // This object will tell you everything you need to know about the incoming user.
    }
    

    【讨论】:

      猜你喜欢
      • 2019-04-17
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-29
      • 2019-07-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多