Authentication webapi中的基本身份验证

Authentication webapi中的基本身份验证,authentication,basic-authentication,asp.net-web-api,Authentication,Basic Authentication,Asp.net Web Api,我开始研究WebAPI,只想创建一个简单的基本身份验证。我想知道怎么做 我尝试使用给定的MSDN链接,但没有提供有关MSDN的分步教程。 您提供的链接提供了您需要的大部分详细信息,我希望这能填补空白 注意:如果使用Web.API 2,Microsoft建议使用另一种方法 在服务器上设置https 这是非常重要的,如果你需要真正的安全,否则密码可以收集窥探方。如何做到这一点完全取决于您的设置,您不需要详细说明,但如果您使用的是Azure WebRole,则Microsoft提供了一个非常好的解决方

我开始研究WebAPI,只想创建一个简单的基本身份验证。我想知道怎么做

我尝试使用给定的MSDN链接,但没有提供有关MSDN的分步教程。

您提供的链接提供了您需要的大部分详细信息,我希望这能填补空白

注意:如果使用Web.API 2,Microsoft建议使用另一种方法

在服务器上设置https 这是非常重要的,如果你需要真正的安全,否则密码可以收集窥探方。如何做到这一点完全取决于您的设置,您不需要详细说明,但如果您使用的是Azure WebRole,则Microsoft提供了一个非常好的解决方案

接下来的步骤不需要这样做,但应该在发布代码之前完成。我首先提到它,因为这一部分通常涉及到让其他人参与(服务器配置的系统管理员、购买证书的财务人员等),最好给他们很多警告

编写(或窃取)自定义IHTTP模块以进行身份验证 这是一大块C#代码——它解析浏览器发送的值,并将HttpContext.Current.User设置为经过身份验证的用户。只需在您自己的应用程序中将这些内容复制并粘贴到一个类中,我们将稍后再进行讨论。您需要在代码中使用以下语句

using System; using System.Net.Http.Headers; using System.Security.Principal;
using System.Text; using System.Threading; using System.Web;
将该模块与应用程序相关联 将新模块添加到web.config文件(注意system.webServer可能已经存在)


如果用户名和密码有效,则将其更改为返回true。如果您正在使用自己的,您可能需要进行调查(您信任从网上下载的实现吗?),或者(简单但不太安全)但是微软可能有更好的东西,因为人们对正确存储密码有很多担忧。

我不得不在MSDN示例中添加几行代码才能使其正常工作。具体来说,在OnApplicationAuthenticateRequest()中,如果无法验证用户,我将响应状态代码设置为401:

private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
        {
            var request = HttpContext.Current.Request;
            var authHeader = request.Headers["Authorization"];
            bool validated = false;
            if (authHeader != null)
            {
                var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);

                // RFC 2617 sec 1.2, "scheme" name is case-insensitive
                if (authHeaderVal.Scheme.Equals("basic",
                                                StringComparison.OrdinalIgnoreCase) &&
                    authHeaderVal.Parameter != null)
                {
                    validated = AuthenticateUser(authHeaderVal.Parameter);
                }
            }

            if (!validated)
            {
                HttpContext.Current.Response.StatusCode = 401;
            }
        }

一旦我这样做了,它工作得很好。可能有更好的方法来构造逻辑,但这是与执行此任务的示例相比的最小变化。

要有选择地在每个控制器或每个方法的基础上启用基本身份验证,您可以从中所述的
AuthorizeAttribute
派生。

这是一篇很棒的文章!我看到的一个更好的回答,真的帮助我更多地了解了BasicAuth,以及如何按照我需要的方式设置它。谢谢加密类有什么不安全的地方?看起来它使用的是PBKDF2,这正是您想要的:Crypto类只进行了1000次迭代,这是2000年发布的中建议的最小迭代次数,而且它不允许您更改该值(您引用的代码将其作为常量)。环顾四周,你会发现自2000年以来每年都会有两倍的建议——但它确实应该根据你的部署硬件进行调整,因为这是在易受攻击性和对用户的影响之间进行权衡。有关更多详细信息,请参见此问题:通过修改,每个请求都将被验证,即使是那些可能不需要验证的请求。当authHeader为null时,validate将保持为false,您将返回401。嗯,不需要身份验证的页面/资源(即用[AllowAnonymous]修饰的控制器/操作)将丢失authHeader…对吗?或者我需要更多的咖啡:)你可能是对的。我还在学这些东西。此后,我将实现从HttpModule更改为HttpHandler,但您的评论仍然适用-如果我有一个带有[AllowAnonymous]的页面,它仍在尝试进行身份验证。如果你知道更好的方法,我洗耳恭听。OP发布的链接中的代码无需任何修改即可工作。你不需要
If(!validated){…}
block-我相信
onapplicationedrequest()
方法“处理”了这个问题。相关问题:
[Authorize] // Restricts access to whole controller    
public class StockController : ApiController {
    [Authorize] // Restricts access to this action - not necessary if whole controller restricted.
    public IEnumerable<StockLevel> Get() {
// TODO: Here is where you would validate the username and password.
private static bool CheckPassword(string username, string password)
private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
        {
            var request = HttpContext.Current.Request;
            var authHeader = request.Headers["Authorization"];
            bool validated = false;
            if (authHeader != null)
            {
                var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);

                // RFC 2617 sec 1.2, "scheme" name is case-insensitive
                if (authHeaderVal.Scheme.Equals("basic",
                                                StringComparison.OrdinalIgnoreCase) &&
                    authHeaderVal.Parameter != null)
                {
                    validated = AuthenticateUser(authHeaderVal.Parameter);
                }
            }

            if (!validated)
            {
                HttpContext.Current.Response.StatusCode = 401;
            }
        }