什么是CookieAuthenticationOptions.AuthenticationType用于?

时间:2016-02-26 13:48:51

标签: asp.net authentication cookies asp.net-identity

在我的应用程序的Asp.Net Identity Auth中间件设置中我有

app.UseCookieAuthentication(new CookieAuthenticationOptions {
    LoginPath = new PathString("/Login/"),
    //AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    Provider = new CookieAuthenticationProvider {
    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<MyUserManager, MyUser>(
                        TimeSpan.FromMinutes(30),
                        (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)
                    ),
    },
});

我从另一个应用程序复制了这个,我注意到如果我取消注释AuthenticationType行,登录成功(我从我的控制器写入记录器中的成功消息)但总是重定向回登录屏幕

documentation for CookieAuthenticationOptions中说

  

选项中的AuthenticationType对应于IIdentity AuthenticationType属性。可以分配不同的值,以便在管道中多次使用相同的身份验证中间件类型。(继承自AuthenticationOptions。)

我真的不明白这意味着什么,为什么这会导致我的登录请求被重定向(成功登录后不会更少),以及此选项 对此有用。

3 个答案:

答案 0 :(得分:5)

这是一个字符串,可以是任何东西。但这是身份验证类型的标识符。您可以拥有多种身份验证类型:您的数据库与用户,Google,Facebook等等。据我所知,这是在登录时添加为生成的Cookie的声明。

您在签出用户时需要知道身份验证提供程序。如果您的身份验证中间件定义如下:

    app.UseCookieAuthentication(new CookieAuthenticationOptions {
        LoginPath = new PathString("/Login/"),
        AuthenticationType = "My-Magical-Authentication",
        // etc...
        },
    });

然后为用户签名,您需要相同的魔术字符串:AuthenticationManager.SignOut("My-Magical-Authentication")

创建主体时,此字符串也会传递到ClaimsIdentity。如果没有AuthenticationType主体,则无法进行身份验证because

/// <summary>
/// Gets a value that indicates whether the identity has been authenticated.
/// </summary>
/// 
/// <returns>
/// true if the identity has been authenticated; otherwise, false.
/// </returns>
public virtual bool IsAuthenticated
{
  get
  {
    return !string.IsNullOrEmpty(this.m_authenticationType);
  }
}

此方法IsAuthenticated用于整个MVC代码库,所有身份验证机制都依赖于此。

理论上,您也可以通过多个提供商登录,一次只注销其中一个,其他提供商仍然可以进行身份​​验证。虽然我从未尝试过这个。

我刚发现的另一个用途 - 如果您未在中间件配置中提供CookieName,那么Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Options.AuthenticationType;see second if statement in constructor)。

我确信有更多地方可以使用它。但最重要的是提供它并与名称保持一致,否则您将在身份验证系统中遇到微妙的错误。

答案 1 :(得分:4)

我不知道答案的全部内容,但我有一个关于 有用的例子。

我有一个多租户网站:该网站作为单个实例运行,多个域链接到它。每个域都是一个单独的租户(具有一组单独的用户)。为了实现每个租户的Facebook登录,我需要每个租户一个Facebook应用程序。要配置此功能,我必须为每个租户设置一个唯一的CallbackPath 唯一的AuthenticationType:

var facebookOptions = new FacebookAuthenticationOptions
{
    AuthenticationType = "Facebook-{tenantID}", 
    CallbackPath = new PathString($"/signin-facebook-{tenantID}")
}

我认为它也被用作cookie名称,但对于像FacebookAuthentication这样的外部登录并非如此。我注意到的是,在请求时弹出了AuthenticationType的值:

  1. IdentityUserLogin.LoginProvider通过authenticationManager.GetExternalLoginInfoAsync()
  2. AuthenticationDescription.AuthenticationType通过authenticationManager.GetExternalAuthenticationTypes()(看似合乎逻辑; - ))
  3. 每个user.Logins的IdentityUserLogin.LoginProvider(类似于1)
  4. 最后但并非最不重要:AuthenticationType的值存储在数据库列AspNetUserLogins.LoginProvider中。

答案 2 :(得分:3)

如果您设置了新的asp.net解决方案,则Startup.Auth 中的标准设置代码(与您从其他应用复制的代码相对)包括行{{1} }

这将创建一个cookie(默认名称为.AspNet.ApplicationCookie),如果您查看浏览器的活动cookie列表,您可以看到该cookie(用于其他内容)以检查用户是否已通过身份验证对于每个请求。如果cookie不存在(或者用户在某种程度上未经过身份验证),则中间件会重定向到行AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,中指定的路由

此行已在您的代码中注释掉并且您的应用有效,这表明您的代码中有一些其他非标准配置可用于对用户进行身份验证。如果取消注释此行并登录成功但重定向回登录,则表明非标准代码与中间件之间存在一些冲突,导致中间件确定用户未经过身份验证,并被重定向回LoginPath

我会查找您的应用中是否存在非标准身份验证代码,并确定具体执行的操作,并且冲突的答案应该出现。一般建议不是要更改标准的身份验证代码,除非您确切知道这样做的含义是什么(并且它可能会变得复杂,并且有大量的陷阱为不警惕)。

具体到您的问题,此选项不仅有用,它对Identity中间件的标准操作至关重要。您的应用中似乎有非标准代码。如果是这样,您应该完全确定它在登录安全方面的作用(及其含义),或者如果可以,则恢复到标准身份代码。