在ASP.NET MVC3应用程序中同时拥有多个身份验证提供程序?

时间:2012-01-19 00:04:06

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

客户端应用程序正在将“块”中的音频文件上载到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(或其他一些auth方法),则允许操作。

ASP.NET MVC3中是否可以使用它?

1 个答案:

答案 0 :(得分:1)

正如评论中所述,您可以创建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")
  }
}