ASP.NET Identity 2是否支持匿名用户?

10

我想允许未注册用户和已注册用户在我的网站上发布内容。

Posts (table)
- Id (int)
- Subject (nvarchar)
- Body (nvarchar)
- UserId (uniqueidentifier)

这个项目使用最新的MS技术(如ASP.NET MVC 5+、C#...)。我该如何操作?

ASP.NET Identity是否是正确的解决方案?

以下三种方式有什么区别:

  • ASP.NET Identity
  • SimpleMembership
  • Membership Provider

更新 我需要能够区分尚未注册的用户并记录他们在数据库中的帖子。

更新2 然后可以选择迁移到已注册的帐户,就像stackoverflow曾经允许匿名用户做的那样。类似于这样但与ASP.NET Identitfy兼容 http://msdn.microsoft.com/en-us/library/ewfkf772(v=vs.100).aspx


身份验证不支持匿名用户... 这有点违背初衷。 匿名用户只是尚未登录的用户。 因此,您的网站必须通过允许匿名用户进入这些页面来支持它们。 - Erik Funkenbusch
这个能和ASP.NET Identity一起使用吗?http://msdn.microsoft.com/en-us/library/ewfkf772(v=vs.100).aspx - James
不,正如我所说的,它也不能与Membership一起使用。Membership和Identity只与经过身份验证的用户有关。 - Erik Funkenbusch
@James,请看下面的回答。我添加了一些使用Identity来确定用户是否已注册的示例代码。这个回答解决了你的问题吗? - Ryan Erdmann
你把匿名配置和会员混淆了。当你使用匿名配置时,确实会在aspnet_Users表中为匿名用户创建一行记录,但这更多是一个实现细节,因为配置和会员都基于aspnet_Users。配置不适用于ASP.NET Identity,因此这个技术细节不适用。 - Erik Funkenbusch
显示剩余6条评论
5个回答

6
我想回答一个最初的问题:“我需要能够区分未注册用户并记录他们在数据库中的帖子。”
我之前使用过Simple Membership,并且现在正在使用Asp.Net Identity Framework 2.2.1。在这两种情况下,我都使用匿名身份验证来区分已注册用户和未注册用户。
以下是步骤:
1. 通过添加``到Web.config启用匿名身份验证。 2. 您可以使用`Request.AnonymousID`获取匿名ID。该ID以字符串格式表示GUID。 3. 如其他用户所述,您可以使用任何身份验证系统,但请记住在注销过程中清除匿名ID。通常,在用户成功验证后,您会将用户名/用户ID与匿名ID保存到持久性存储中。通过在用户注销时清除匿名ID,您可以确保其他已认证的用户无法与相同的匿名ID相关联。 4. 您可以使用`AnonymousIdentificationModule.ClearAnonymousIdentifier()`来清除匿名ID。注意:`AnonymousIdentificationModule`位于System.Web.Security程序集中。您可以添加对System.Web的引用或在代码中使用CTRL +“.”来引入System.Web.Security中的`AnonymousIdentificationModule`。

1
感谢您提供有关匿名身份验证的信息。这在我的MVC项目中帮了我很多,因为我需要一个匿名用户的标识符来缓存一些数据,而不依赖于Session模块。+1 - dizarter
1
@dizarter:不客气,很高兴能帮到你。遗憾的是,ASP.NET Core的匿名身份验证功能已经消失了,看起来你需要自己实现:https://dev59.com/1Z7ha4cB1Zd3GeqPoMPS - David Liang
再次感谢您提供有关ASP.NET Core的信息。我现在不需要它,但将来肯定会派上用场。 - dizarter

5
ASP.NET Identity是ASP.NET中最新鉴权的修订版,它的前身是SimpleMembership,这本身就是对旧版ASP.NET Auth的改进尝试。会员提供程序不是单独的身份验证系统,而是用于通过附加功能启动ASP.NET Auth或SimpleMembership的一种方式。如果默认情况下没有涵盖特定的登录方案,则可以创建一个会员提供程序,允许ASP.NET与该系统进行交互。
ASP.NET Identity取代了其他所有内容,并且不使用会员提供程序。相反,它提供了一个非常可扩展的身份验证基础,通过使用标准API,允许您以任何方式自定义身份验证。它还具有更强大的OAuth和外部登录提供程序支持,并且与像Active Directory这样的东西(特别是云中的Azure版本)更好地接口。
如果您正在开始一个新项目,请选择Identity。虽然微软过去似乎经常更换身份验证方式,但从我个人的经验来看,他们似乎已经搞定了。我认为您只会看到进一步的完善和改进,而不是完全替代。

ASP.NET身份认证 > SimpleMembership > 成员提供程序,对吗? - James
1
是的,那通常是正确的。您应该在新项目中使用 Identity。 - Ryan Erdmann
1
ASP.NET > SimpleMembership,是的。Membership提供程序是SimpleMembership的必然结果,而不是某种不同类型的身份验证机制。 - Chris Pratt

1
ASP.NET身份验证系统旨在取代先前的ASP.NET Membership和Simple Membership系统。它包括配置文件支持、OAuth集成,与OWIN一起使用,并包含在Visual Studio 2013附带的ASP.NET模板中。
ASP.NET用户配置文件功能旨在提供特定于当前用户的信息。配置文件可以与已验证的用户或匿名(非验证)用户一起工作。
在某些情况下,您的应用程序可能最初维护匿名用户的个性化信息,但最终该用户登录到您的应用程序。这种情况下,用户的身份从分配的匿名用户身份更改为身份验证过程提供的身份。
当用户登录时(即停止成为匿名用户),将引发MigrateAnonymous事件。如果需要,您可以处理此事件以将信息从用户的匿名身份迁移到新的经过身份验证的身份。

http://msdn.microsoft.com/en-us/library/vstudio/ewfkf772(v=vs.100).aspx

最佳迁移匿名配置文件的方法

http://odetocode.com/articles/440.aspx

public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)
{
  ProfileCommon anonymousProfile = Profile.GetProfile(args.AnonymousID);

  Profile.ZipCode = anonymousProfile.ZipCode;
  Profile.CityAndState = anonymousProfile.CityAndState;
  Profile.StockSymbols = anonymousProfile.StockSymbols;

  ////////
  // Delete the anonymous profile. If the anonymous ID is not 
  // needed in the rest of the site, remove the anonymous cookie.

  ProfileManager.DeleteProfile(args.AnonymousID);
  AnonymousIdentificationModule.ClearAnonymousIdentifier(); 

  // Delete the user row that was created for the anonymous user.
  Membership.DeleteUser(args.AnonymousID, true);

}

1

ASP.NET身份验证是一个灵活的框架,用于处理Web应用程序中的用户身份验证。它非常棒,我强烈建议您在项目中继续使用它。

Identity不支持匿名用户,而是一个框架,让您管理已经通过身份验证的用户。Identity将允许您维护本地用户,或者如果您想要,通过外部服务(例如Facebook或Google)进行身份验证的用户。

看起来您希望您的Web应用程序的一部分可以访问未经身份验证的用户。您可以通过在ASP.NET控制器上添加属性来实现这一点。

[Authorize]属性添加到控制器或控制器方法将告诉MVC确保用户已经通过身份验证并且已被授权。然而,要允许匿名用户,只需在您想要公开访问的方法上放置[AllowAnonymous]属性即可。

但是,您仍然可以知道用户是否已经通过身份验证。考虑以下示例控制器和方法:

[Authorize]
public class PostController : Controller
{
    [AllowAnonymous]
    public ActionResult Index()
    {
        var isAuthenticated = User.Identity.IsAuthenticated;

        return View();
    }
}

isAuthenticated 可以让你知道当前用户是否已登录,如果已经登录,你可以从 User.Identity 对象中获取更多信息。


关于会员框架之间的区别的一般问题,我将转而参考官方文档,该文档对差异进行了很好的概述: http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity。 您肯定希望在您的Web应用程序中使用ASP.NET Identity。

更新 查看这个示例代码,它将帮助您区分在记录帖子到数据库时尚未注册的用户。

[Authorize]
public class PostController : Controller
{
    [AllowAnonymous]
    public HttpStatusCodeResult CreatePost(string postText)
    {
        // Use ASP.NET Identity to see if the user is logged in.  
        // If they are, we can get their User Id (blank otherwise)
        var isAuthenticated = User.Identity.IsAuthenticated;
        var userId = "";
        if (isAuthenticated)
            userId = User.Identity.GetUserId();

        // Create a new post object
        var post = new
        {
            PostText = postText,
            Anonymous = !isAuthenticated,
            UserId = userId
        };

        // Save the post to the database here

        return new HttpStatusCodeResult(HttpStatusCode.OK);
    }
}

我认为他想追踪用户的匿名帖子,以允许他们编辑自己的帖子(但不是其他匿名用户)。你的方法不会允许这样做。 - Erik Funkenbusch
是的,就像StackOverflow以前允许匿名发布一样。 - James
啊,我明白了。我很快会添加另一个答案。 - Ryan Erdmann

1
一种处理方法是使用基于 cookie 的身份验证方式。浏览器会随每个 Web 请求发送与您的域相关联的任何 cookie,因此它们是处理身份验证的简单方法。这里的想法是我们将有一个名为“ident”的 cookie,其中将存储我们生成的用户 ID。我正在使用 Guids,但您也可以轻松地在 DB 中创建一个条目。当我们得到 Web 请求时,检查 cookie 是否存在。如果存在,则在 cookie 中拥有其用户 ID。否则,为他们生成一个新的用户 ID 并设置 cookie。
它不完美...如果用户清除 cookie,您将失去识别他们的能力,但这可能是您最好的选择。以下是一些可用于项目并进行测试的工作代码:
public class PostController : Controller
{
    [HttpGet]
    public ActionResult Index(string text)
    {
        if (string.IsNullOrWhiteSpace(text))
            return Content("Please specifiy a value for text.  i.e. /Post/Index?text=Message");

        var message = "";

        var isAuthenticated = Request.Cookies["ident"] != null;
        if (isAuthenticated)
        {
            var userId = Request.Cookies["ident"].Value;
            var post = new
            {
                Text = text,
                User = userId
            };
            // Save to database here
            message = "You are a previously recognized user, with UserId=" + userId;
        }
        else
        {
            var userId = Guid.NewGuid().ToString();
            var identCookie = new HttpCookie("ident", userId);
            Response.Cookies.Add(identCookie);

            var post = new
            {
                Text = text,
                User = userId
            };
            // Save to database
            message = "You are a new anonymous user. Your new UserId=" + userId;
        }

        return Content(message);
    }
}

如果您最终采用这种方法并且想要在多个请求中重复使用此逻辑,我强烈建议将其抽象成一个实用类,或者更好的方法是在控制器中重写IPrincipal User属性。请查看[这里](ASP.NET MVC - Set custom IIdentity or IPrincipal),了解有关设置自定义IPrincipal的更多信息。

Ident cookie是ASP.NET Identity生成的吗?它能被欺骗吗? - James
身份验证 cookie 并不是 ASP.NET 的特定功能,但我们允许 ASP.NET 处理为请求创建 cookie。是的,它可能会被欺骗,但你正在处理匿名用户,所以我认为这个问题并不重要。 - Ryan Erdmann
我希望允许匿名和注册用户进行发布。这就是我问有关ASP.NET Identitfy的原因。更新了问题以使其更清晰。 - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接