【问题标题】:Is having multiple authentication providers at the same time possible in ASP.NET MVC3 application?在 ASP.NET MVC3 应用程序中是否可以同时拥有多个身份验证提供程序?
【发布时间】:2012-01-19 00:04:06
【问题描述】:

客户端应用程序正在将“块”中的音频文件上传到 MVC3 站点。客户端使用HttpWebRequest POST 来执行此操作。

在服务器上,我有以下控制器操作:

  [Authorize]
  [HttpPost]
  public JsonResult RecieveChunk(string id, [ModelBinder(typeof(AudioChunkModelBinder))] byte[] audio)
        {
            //Process chunk

            var chunk = new AudioChunk
            {
                ThoughtId = Guid.Parse(id),
                Data = audio
            };

            //Process chunk by BL

            return new JsonResult {Data = "Success"};
        }

目前,内置的AspNetMemebershipProvider正在处理授权,因此客户端应用程序必须首先在登录页面进行身份验证,将cookie获取到CookieContainer,然后调用服务器以上传一大块数据。

我想让客户端也能够匿名上传音频文件到服务器,而无需事先注册。每次从同一设备上传文件时,客户端应用程序代码都会提供相同的 guid。

我希望两类用户共享相同的RecieveChunk 操作来执行此操作。但必须以匿名方式(仅使用guid)或使用登录/密码组合对它们进行授权。

我可以将两个不同的控制器链接到两个不同的身份验证提供程序吗?第三个控制器,具有[Authorize] 标记的操作,如果任一提供程序已向用户提供 cookie(或其他某种身份验证方法),则将允许操作。

在 ASP.NET MVC3 中一般可以吗?

【问题讨论】:

  • 从您在这里所说的来看,您的上传操作确实不需要需要授权,因此不应该具有该属性。相反,您应该使用 Action 中的代码来确定他们是否已登录,并采取相应的行动。
  • 是的,这就是我正在做的。所以我假设答案是——不,只有一个成员资格提供程序的实现同时在应用程序范围内起作用?
  • 嗯,不;那不是你在做什么。你在那里有 Authorize 属性。此外,根据定义,匿名用户未经过身份验证。所以你正在寻找的是不是多个会员提供者。
  • @AndrewBarber,对不起,我的英语造成了混乱。我的意思是,在我阅读您最初的评论之前,我继续执行您提到的操作 - 开始将匿名用户视为未经身份验证的用户,删除 [Authorize]。
  • 啊,好的!是的;不直接支持两个成员资格提供程序。您当然可以使用自己的操作过滤器而不是授权来实现自己的系统。

标签: asp.net-mvc-3 httpwebrequest asp.net-membership authorization


【解决方案1】:

如 cmets 中所述,您可以创建 FilterAttribute class 的自定义实现并实现 IAuthorizationFilter interface。例如这里是ChildActionOnlyAttribute 的实现:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class ChildActionOnlyAttribute : FilterAttribute, IAuthorizationFilter
{
  public void OnAuthorization(AuthorizationContext filterContext)
  {
    if (filterContext == null)
      throw new ArgumentNullException("filterContext");
    if (!filterContext.IsChildAction)
      throw Error.ChildActionOnlyAttribute_MustBeInChildRequest(filterContext.ActionDescriptor);
  }
}

这是RequireHttpsAttribute 的实现:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireHttpsAttribute : FilterAttribute, IAuthorizationFilter
{
  public virtual void OnAuthorization(AuthorizationContext filterContext)
  {
    if (filterContext == null)
      throw new ArgumentNullException("filterContext");
    if (filterContext.HttpContext.Request.IsSecureConnection)
      return;
    this.HandleNonHttpsRequest(filterContext);
  }

  protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext)
  {
    if (!string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
      throw new InvalidOperationException(MvcResources.RequireHttpsAttribute_MustUseSsl);
    string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
    filterContext.Result = (ActionResult) new RedirectResult(url);
  }
}

所以你可以这样做:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class CustomAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
  public void OnAuthorization(AuthorizationContext filterContext)
  {
    if (filterContext == null)
      throw new ArgumentNullException("filterContext");

    var guidPresent = CheckForGuid();

    if (!filterContext.HttpContext.User.Identity.IsAuthenticated && !guidPresent)
      throw new InvalidOperationException("Must authenticate properly")
  }
}

【讨论】:

    猜你喜欢
    • 2016-11-18
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    相关资源
    最近更新 更多