为什么使用ASP.NET Identity Core时OAuth失败?

时间:2019-03-18 23:24:08

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

我有一个具有以下配置的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提供程序返回用户的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

要结合使用OAuth和Asp.Net Core身份,您需要将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";
    });

答案 1 :(得分:1)

当结合使用ASP.NET Identity和OAuth时,需要注意以下事项:

配置服务:

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

获取外部用户作为ClaimsPrincipal:

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

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

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

获取外部用户为ExternalLoginInfo

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

  1. 他们来自什么供应商?
  2. 他们在提供者上的唯一密钥是什么?

您的服务应配置如下:

services.AddAuthentication()
    .AddFacebook(options =>
    {
        options.AppId = "";
        options.AppSecret = "";
    });

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<MyDbContext>();

在您的登录控制器中,将SignInManager<TUser>注入:

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.
}