Asp.net mvc ASP.NET MVC-HTTP身份验证提示

Asp.net mvc ASP.NET MVC-HTTP身份验证提示,asp.net-mvc,http,authentication,basic-authentication,Asp.net Mvc,Http,Authentication,Basic Authentication,在呈现视图之前,是否可以让我的应用程序请求用户名和密码提示? 就像在twitter API上获取有关您帐户的信息一样: 因此,在呈现视图| |文件之前,它会要求您插入用户名和密码,我认为这是直接在服务器上进行的,因为curl请求基于username:password以及以下内容: curl -u user:password http://twitter.com/account/verify_credentials.xml 当我试图按照相同的结构构建API时,我想知道如何在ASP.NET MV

在呈现视图之前,是否可以让我的应用程序请求用户名和密码提示? 就像在twitter API上获取有关您帐户的信息一样:

因此,在呈现视图| |文件之前,它会要求您插入用户名和密码,我认为这是直接在服务器上进行的,因为curl请求基于username:password以及以下内容:

curl -u user:password http://twitter.com/account/verify_credentials.xml
当我试图按照相同的结构构建API时,我想知道如何在ASP.NET MVC#上实现这一点。我已经在ruby rails上使用过它,它非常简单,比如:

before_filter :authenticate

def authenticate
    authenticate_or_request_with_http_basic do |username, password|
    username == "foo" && password == "bar"
end
我不认为[授权]过滤器是相同的,因为我相信它只是一个重定向, 它会将您重定向到基于Accounts数据库的Accounts Internal Controller,在本例中,我将使用另一个数据库,特别是来自Web服务的数据库,并在提交信息后进行验证。 但是我需要操作来要求用户并根据其请求传递凭据

提前谢谢


更新:

实际请求需要此身份验证的页面(即Twitter) 我必须根据它的要求宣布这一点

request.Credentials = new NetworkCredential("username", "password");
这将反映提示的用户名和密码

所以,这完全是一样的,但是从另一方面来说,如果可以在请求时向身份验证提示符提供信息,那么我怎么能在请求时要求这种身份验证呢

因此,每当有人试图向我的应用程序发出请求时,例如:

它应该在服务器提示下请求用户名和密码 例如,要检索关于旋度的信息,它是这样的

curl -u user:password http://myapplication/clients/verify_credentials

嗯,要要求基本身份验证,您需要返回401状态码。但这样做将导致当前身份验证模块执行其默认的未经授权处理程序(对于表单身份验证,这意味着重定向到登录页面)

我写了一个
actionfilteratribte
,看看在
web.config
中没有安装身份验证模块时,我是否可以获得您想要的行为

public class RequireBasicAuthentication : ActionFilterAttribute {
   public override void OnActionExecuting(ActionExecutingContext filterContext) {
       var req = filterContext.HttpContext.Request;
       if (String.IsNullOrEmpty(req.Headers["Authorization"])) {
           var res = filterContext.HttpContext.Response;
           res.StatusCode = 401;
           res.AddHeader("WWW-Authenticate", "Basic realm=\"Twitter\"");
           res.End();
       }
   }
}
以及控制器动作:

[RequireBasicAuthentication]
public ActionResult Index() {
    var cred = System.Text.ASCIIEncoding.ASCII
            .GetString(Convert.FromBase64String(
            Request.Headers["Authorization"].Substring(6)))
            .Split(':');
    var user = new { Name = cred[0], Pass = cred[1] };
    return Content(String.Format("user:{0}, password:{1}", 
        user.Name, user.Pass));
}

该操作成功打印我输入的用户名和密码。但我真的怀疑这是最好的方法。除了这样要求用户名和密码,你别无选择吗?

根据我所读的内容,你真的想创建一个服务而不是一个web应用程序。我在这里猜测,但我认为您选择ASP.NETMVC是为了利用路由优势,并按照您想要的方式构建URL?如果我错了,请纠正我

在我看来,如果要返回数据,解决问题的最佳方法是使用WCF构建RESTful web服务。如果你想走这条路,这应该可以帮助你开始


否则,您将需要进一步处理请求并对其进行身份验证。如果是这种情况,我可以帮助提供更多信息和代码。

以下是对我有效的方法。这是一个小小的脚工作,但它将使IIS和MVC3的行为更像所有其他基本Http身份验证系统,如Apache

第一步

确保为IIS安装了“基本身份验证”

(示例:控制面板->程序和功能->打开或关闭Windows功能)

*目前我正在使用Windows7,不确定确切的路径。[谷歌:在IIS中安装基本身份验证]应该可以让你接近

第二步

确保在您的站点下启用了基本身份验证。如果必须在上一步中安装此程序,则需要确保重置IIS服务,并且所有应用程序池都已关闭

第三步

(注意:我使用的是MVC3,我觉得它应该可以在大多数模型中使用,包括ASP.Net,而不需要太多麻烦。)
在项目中,您需要添加以下类:

步骤3a。[编辑]

以下是您将“使用”的不同LIB

只是想把它们扔进去。我讨厌人们把他们排除在外

第四步

将以下内容添加到web配置中。请注意,我包括周围的结构,例如“配置”标签。。。这只是一个路线图,如果你已经有一个“配置”标签,不要添加其他标签,否则IIS会对你感到不安


请注意,{Namespace}.ServiceModule中的名称空间是您将步骤3中的类放入的名称空间


…差不多就是这样。

我修改了çağdaş答案,将整个逻辑放在我的自定义ActionFilter属性中

public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    public string BasicRealm { get; set; }
    protected string Username { get; set; }
    protected string Password { get; set; }

    public BasicAuthenticationAttribute(string username, string password)
    {
        this.Username = username;
        this.Password = password;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var req = filterContext.HttpContext.Request;
        var auth = req.Headers["Authorization"];
        if (!String.IsNullOrEmpty(auth))
        {
            var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
            var user = new { Name = cred[0], Pass = cred[1] };
            if (user.Name == Username && user.Pass == Password) return;
        }
        var res = filterContext.HttpContext.Response;
        res.StatusCode = 401;
        res.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel"));
        res.End();
    }
}
它可用于对整个控制器进行基本身份验证:

[BasicAuthenticationAttribute("your-username", "your-password", 
    BasicRealm = "your-realm")]
public class HomeController : BaseController
{
   ...
}
或特定的行动结果:

public class HomeController : BaseController
{
    [BasicAuthenticationAttribute("your-username", "your-password", 
        BasicRealm = "your-realm")]
    public ActionResult Index() 
    {
        ...
    }
}
注意:上述实现要求开发人员手动插入用户名和密码作为ActionFilter所需的参数,但可以轻松扩展以使其支持任何授权机制(MembershipProvider、ASP.NET标识、基于外部DBMS或文件的自定义userbase等)通过删除自定义构造函数并相应地修改OnActionExecuting方法IF块


关于其他信息,你也可以在我的博客上写下。

应用程序也使用表单验证吗?实际上表单将使用我正在尝试构建的这个外部接口,因此所有验证和所有内容都应该在请求上进行,就像推特一样,没有任何图形界面。在我的控制器内,我将进行验证。我将更详细地更新我的问题。是的,非常感谢你的帮助,但是的,不幸的是,当你谈到windows平台时,我可以看到事情要复杂得多,至少这是我现在可以说的,因为我不是这方面的专家。但是这不起作用,因为请求本身不需要用户名和密码,这就像一个简单的重定向,并在这个url上使用curl
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    public string BasicRealm { get; set; }
    protected string Username { get; set; }
    protected string Password { get; set; }

    public BasicAuthenticationAttribute(string username, string password)
    {
        this.Username = username;
        this.Password = password;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var req = filterContext.HttpContext.Request;
        var auth = req.Headers["Authorization"];
        if (!String.IsNullOrEmpty(auth))
        {
            var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
            var user = new { Name = cred[0], Pass = cred[1] };
            if (user.Name == Username && user.Pass == Password) return;
        }
        var res = filterContext.HttpContext.Response;
        res.StatusCode = 401;
        res.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel"));
        res.End();
    }
}
[BasicAuthenticationAttribute("your-username", "your-password", 
    BasicRealm = "your-realm")]
public class HomeController : BaseController
{
   ...
}
public class HomeController : BaseController
{
    [BasicAuthenticationAttribute("your-username", "your-password", 
        BasicRealm = "your-realm")]
    public ActionResult Index() 
    {
        ...
    }
}