首页 文章

ASP.NET Web API中的用户身份验证

提问于
浏览
146

这个话题对我来说非常困惑 . 我是HTTP应用程序的新手,但需要开发一个消费来自某个地方的JSON数据的iPhone客户端 . 我选择了MS的Web API,因为它似乎很容易,但是当涉及到对用户进行身份验证时,事情变得非常令人沮丧 .

令人惊讶的是,我几乎无法找到一个明确的示例,说明如何在登录屏幕上对用户进行身份验证,直到使用 ApiController 属性覆盖我的 ApiController 方法几个小时的Google搜索后 .

这不是一个问题,而是一个如何准确地执行此操作的示例的请求 . 我看过以下几页:

即使这些解释了如何处理未经授权的请求,但这些并没有明确地证明像 LoginController 之类的东西要求用户凭证并验证它们 .

有人愿意写一个很好的简单例子或指出我正确的方向吗?

谢谢 .

3 回答

  • 176

    令我感到惊讶的是,在几个小时的Google搜索后,我无法找到一个明确的示例,说明如何从登录屏幕向下验证用户身份以及使用Authorize属性覆盖我的ApiController方法 .

    那是因为你对这两个概念感到困惑:

    • 身份验证是系统可以安全地识别其用户的机制 . 身份验证系统提供问题的答案:

    • 谁是用户?

    • 用户真的是他/她代表自己的人吗?

    • 授权是一种机制,通过该机制,系统可以确定特定经过身份验证的用户对系统控制的安全资源应具有的访问级别 . 例如,可以设计数据库管理系统,以便为某些指定的个人提供从数据库检索信息的能力,但不能改变存储在数据库中的数据,同时使其他人能够更改数据 . 授权系统提供问题的答案:

    • 用户X是否有权访问资源R?

    • 用户X是否有权执行操作P?

    • 用户X是否被授权在资源R上执行操作P?

    MVC中的 Authorize 属性用于应用访问规则,例如:

    [System.Web.Http.Authorize(Roles = "Admin, Super User")]
     public ActionResult AdministratorsOnly()
     {
         return View();
     }
    

    以上规则仅允许 users in the Admin and Super User roles to access the method

    也可以使用 location 元素在web.config文件中设置这些规则 . 例:

    <location path="Home/AdministratorsOnly">
        <system.web>
          <authorization>
            <allow roles="Administrators"/>
            <deny users="*"/>
          </authorization>
        </system.web>
      </location>
    

    但是,在执行这些授权规则之前,您必须是 authenticated to the current web site .

    尽管这些解释了如何处理未经授权的请求,但这些请求并没有明确地证明像LoginController或类似的东西要求用户凭据并验证它们 .

    从这里开始,我们可以将问题分成两部分:

    • 在同一Web应用程序中使用Web API服务时对用户进行身份验证

    这将是最简单的方法,因为你会依赖Authentication in ASP.Net

    这是一个简单的例子:

    Web.config

    <authentication mode="Forms">
      <forms
        protection="All"
        slidingExpiration="true"
        loginUrl="account/login"
        cookieless="UseCookies"
        enableCrossAppRedirects="false"
        name="cookieName"
      />
    </authentication>
    

    用户将被重定向到帐户/登录路由,在那里您将呈现自定义控件以询问用户凭据,然后您将使用以下命令设置身份验证cookie:

    if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
    
    • 跨平台身份验证

    这种情况将是 only exposing Web API services within the Web application 因此,您将有另一个客户端使用服务,客户端可能是另一个Web应用程序或任何.Net应用程序(Win Forms,WPF,控制台,Windows服务等)

    例如,假设您将从同一网络域(在Intranet中)的其他Web应用程序中使用Web API服务,在这种情况下,您可以依赖ASP.Net提供的Windows身份验证 .

    <authentication mode="Windows" />
    

    如果您的服务在Internet上公开,那么您需要将经过身份验证的令牌传递给每个Web API服务 .

    有关更多信息,请获取以下文章的战利品:

  • 14

    如果要对 user name and passwordwithout an authorization cookie 进行身份验证,MVC4 Authorize属性将赢得't work out of the box. However, you can add the following helper method to your controller to accept basic authentication headers. Call it from the beginning of your controller'方法 .

    void EnsureAuthenticated(string role)
    {
        string[] parts = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(Request.Headers.Authorization.Parameter)).Split(':');
        if (parts.Length != 2 || !Membership.ValidateUser(parts[0], parts[1]))
            throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "No account with that username and password"));
        if (role != null && !Roles.IsUserInRole(parts[0], role))
            throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "An administrator account is required"));
    }
    

    从客户端,此帮助程序创建一个 HttpClient ,其中包含身份验证标头:

    static HttpClient CreateBasicAuthenticationHttpClient(string userName, string password)
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(userName + ':' + password)));
        return client;
    }
    
  • 9

    我正在研究MVC5 / Web API项目,并且需要能够获得Web Api方法的授权 . 首次加载我的索引视图时,我调用了'token'Web API方法,我认为该方法是自动创建的 .

    获取令牌的客户端代码(CoffeeScript)是:

    getAuthenticationToken = (username, password) ->
        dataToSend = "username=" + username + "&password=" + password
        dataToSend += "&grant_type=password"
        $.post("/token", dataToSend).success saveAccessToken
    

    如果成功,则调用以下内容,以在本地保存身份验证令牌:

    saveAccessToken = (response) ->
        window.authenticationToken = response.access_token
    

    然后,如果我需要对具有[Authorize]标记的Web API方法进行Ajax调用,我只需将以下 Headers 添加到我的Ajax调用中:

    { "Authorization": "Bearer " + window.authenticationToken }
    

相关问题