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

发布于 2024-12-27 21:13:59 字数 1046 浏览 1 评论 0原文

客户端应用程序正在将音频文件以“块”形式上传到 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 中可能吗?

A client application is uploading an audio file in "chunks" to an MVC3 site. A client uses HttpWebRequest POST to do it.

On the server, I have the following controller action:

  [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"};
        }

Currently, a built-in AspNetMemebershipProvider is handling the authorization, so the client app has to first authenticate at the logon page, obtain cookie into a CookieContainer and then make a call to a server to upload a chunk of data.

I want to allow clients to also be able to anonymously upload audio files to the server, without a need to previously register. They the client app code will provide the same guid each time the file is uploaded from the same device.

I want both categories of users to share the same RecieveChunk action to do it. But they must be authrized either anonymously (with just guid), or with the logon/pass combination.

Can I have two different controllers linked to two different authentication providers? The third controller, that has [Authorize] marked action, will allow action if either one provider has given a user a cookie (or some other auth method).

Is it possible in general in ASP.NET MVC3?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月光色 2025-01-03 21:13:59

正如评论中所讨论的,您可以创建 < 的自定义实现code>FilterAttribute 类 并实现 IAuthorizationFilter 接口。例如,这里是 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")
  }
}

As discussed in comments you can create a custom implementation of the FilterAttribute class and implement the IAuthorizationFilter interface. For example here is the ChildActionOnlyAttribute implementation:

[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);
  }
}

And here is the RequireHttpsAttribute implementation:

[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);
  }
}

So you could do something like:

[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")
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文