Asp.net mvc UseCookie身份验证与UseExternalSignInCookie

Asp.net mvc UseCookie身份验证与UseExternalSignInCookie,asp.net-mvc,owin,Asp.net Mvc,Owin,我使用Owin通过Google oAuth进行授权。以下是我的cookie的配置方式: // Enable the application to use a cookie to store information for the signed in user app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.Applic

我使用Owin通过Google oAuth进行授权。以下是我的cookie的配置方式:

// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Authentication/Login")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
因此,我同时使用UseCookie身份验证和UseExternalSignInCookie,这似乎是多余的。我应该为IAAuthenticationManager方法(SignIn、SingOUt等)指定这两种身份验证类型中的哪一种?或者我应该只保留其中一个

更新。最让我困惑的是登录方法:

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
因此,从ExternalCookie中签名,但在ApplicationCookie中签名。

“注销(DefaultAuthenticationTypes.ExternalCookie)”是按照Hao Kung的回答“清理,外部cookie”

Microsoft.aspnet.identity.samples项目中有一个很好的实现,您可以从nuget下载。在这个实现中,他们使用:-

    var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

“ExternalCookie”是“用于配置ExternalSignationThenticationType的默认值”,我相信这意味着它被用作临时cookie,用于根据外部视图验证用户

如果希望Google登录工作,您需要所有这些。这就是它的工作原理。在OWIN管道中,您有三个中间件组件:(1)在主动模式下运行的cookie身份验证中间件,(2)在被动模式下运行的cookie身份验证中间件的另一个实例,以及(3)Google身份验证中间件。就这样吧

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    ...
}); // Active

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // Passive

app.UseGoogleAuthentication(...);
当有401时,你的用户会被重定向到谷歌。在那里,您的用户登录,谷歌验证凭证。谷歌然后将用户重定向回你的应用程序。此时,Google身份验证中间件获取登录信息,应用授权(读取外部cookie)并短路OWIN管道并重定向到外部回调URL,该URL对应于
AccountController
ExternalLoginCallback
操作方法。因此,在这一点上,当请求作为重定向的结果到达你的应用程序时,你会得到带有用户名和电子邮件声明的外部cookie

为了读取此cookie并从Google检索数据(用户名等),您使用在被动模式下运行的cookie身份验证中间件。由于该中间件在被动模式下运行,因此必须告诉它读取cookie。这就是在
ExternalLoginCallback
操作方法中调用
AuthenticationManager.getexternallogininfosync()
时发生的情况。此时,外部cookie中的标识已经建立,并且该标识只包含来自Google的名称和电子邮件声明

通常,此时您需要从应用程序数据存储中检索特定于用户的信息,并向标识添加更多声明。因此,在外部cookie中间件上调用
注销
,这也将确保外部cookie不再通过使其过期而返回。因此,使用当时可用的身份信息,
UserManager.FindAsync
ExternalLoginCallback
操作方法中调用,该方法应返回用户所有特定于应用程序的声明。使用该新标识,可以在活动模式下运行的cookie身份验证中间件上调用
SignIn
。这将确保创建新的cookie。与外部cookie相比,此新cookie包含所有特定于应用程序的声明。随后,您将获得此cookie,并且在活动模式下运行的cookie身份验证中间件将主动读取cookie,并使用所有特定于应用程序的声明的完整列表建立标识

因此,如果您不调用Signin,您将不会创建包含所有特定于应用程序的声明的cookie。但接下来就要由你使用其他的机制了。开箱即用的行为是,通过调用
SignIn
创建包含所有特定于应用程序的声明的本地cookie,然后由在活动模式下运行的cookie中间件读取


更新:我创建了一篇博文,解释了如何不用两个cookie中间件实例就可以脱身

UserManager.FindAsync位现在隐藏在Identity 2.2.0(不是OSS)的SignInManager中,但我相信这仍然是在幕后进行的。由于优化,Reflector没有太多帮助。所以,如果有人试图跟随该位,但在示例代码中找不到它,这就是为什么。这就是它在1.0和2.0中的实现方式,但在2.2中被抽象出来,在vNext中可能又有一点不同。我理解这不是一个身份帖子,但很多人可能都在查看该框架中执行上述操作的示例代码。如果我们调用AuthenticationManager.GetExternalLoginInfoAsync()它第一次返回loginInfo,但如果我们再次登录它将返回null,会发生什么情况。在我们回收应用程序池后,它会再次返回loginInfo@为什么我不能只使用被动中间件?如果我唯一需要的是用户身份(比如Facebook:133454)。