简体   繁体   English

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

[英]User Authentication in ASP.NET Web API

This topic has been incredibly confusing for me. 这个话题令我难以置信。 I am a rookie in HTTP apps but need to develop an iPhone client that consumes JSON data from somewhere. 我是HTTP应用程序的新手,但需要开发一个消费来自某个地方的JSON数据的iPhone客户端。 I chose Web API from MS because it seemed easy enough but when it comes to authenticating users, things get quite frustrating. 我选择了MS的Web API,因为它似乎很容易,但是当涉及到对用户进行身份验证时,事情变得非常令人沮丧。

I am amazed how I've not been able to find a clear example of how to authenticate an user right from the login screen down to using the Authorize attribute over my ApiController methods after several hours of Googling. 令我惊讶的是,在几个小时的Google搜索后,我无法找到一个明确的示例,说明如何从登录屏幕向下验证用户身份以及使用Authorize属性覆盖我的ApiController方法。

This is not a question but a request for an example of how to do this exactly. 这不是一个问题,而是一个如何准确执行此操作的示例请求。 I have looked at the following pages: 我看过以下几页:

Even though these explain how to handle unauthorized requests, these do not demonstrate clearly something like a LoginController or something like that to ask for user credentials and validate them. 尽管这些解释了如何处理未经授权的请求,但这些请求并没有明确地证明像LoginController或类似的东西要求用户凭据并验证它们。

Anyone willing to write a nice simple example or point me in the right direction, please? 有谁愿意写一个很好的简单例子或指出我正确的方向,拜托?

Thanks. 谢谢。

I am amazed how I've not been able to find a clear example of how to authenticate an user right from the login screen down to using the Authorize attribute over my ApiController methods after several hours of Googling. 令我惊讶的是,在几个小时的Google搜索后,我无法找到一个明确的示例,说明如何从登录屏幕向下验证用户身份以及使用Authorize属性覆盖我的ApiController方法。

That's because you are getting confused about these two concepts: 那是因为你对这两个概念感到困惑:

  • Authentication is the mechanism whereby systems may securely identify their users. 身份验证是系统可以安全地识别其用户的机制。 Authentication systems provide an answers to the questions: 身份验证系统提供问题的答案:

    • Who is the user? 谁是用户?
    • Is the user really who he/she represents himself to be? 用户真的是他/她代表自己的人吗?
  • Authorization is the mechanism by which a system determines what level of access a particular authenticated user should have to secured resources controlled by the system. 授权是一种机制,通过该机制,系统可以确定特定的已认证用户对系统控制的安全资源应具有的访问级别。 For example, a database management system might be designed so as to provide certain specified individuals with the ability to retrieve information from a database but not the ability to change data stored in the datbase, while giving other individuals the ability to change data. 例如,可以设计数据库管理系统,以便为某些指定的个人提供从数据库检索信息的能力,但不能改变存储在数据库中的数据,同时使其他人能够更改数据。 Authorization systems provide answers to the questions: 授权系统提供问题的答案:

    • Is user X authorized to access resource R? 用户X是否有权访问资源R?
    • Is user X authorized to perform operation P? 用户X是否被授权执行操作P?
    • Is user X authorized to perform operation P on resource R? 用户X是否被授权在资源R上执行操作P?

The Authorize attribute in MVC is used to apply access rules, for example: MVC中的Authorize属性用于应用访问规则,例如:

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

The above rule will allow only users in the Admin and Super User roles to access the method 上述规则将仅允许管理员超级用户角色中的用户访问该方法

These rules can also be set in the web.config file, using the location element. 也可以使用location元素在web.config文件中设置这些规则。 Example: 例:

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

However, before those authorization rules are executed, you have to be authenticated to the current web site . 但是,在执行这些授权规则之前,必须对当前网站进行身份验证

Even though these explain how to handle unauthorized requests, these do not demonstrate clearly something like a LoginController or something like that to ask for user credentials and validate them. 尽管这些解释了如何处理未经授权的请求,但这些请求并没有明确地证明像LoginController或类似的东西要求用户凭据并验证它们。

From here, we could split the problem in two: 从这里开始,我们可以将问题分成两部分:

  • Authenticate users when consuming the Web API services within the same Web application 在同一Web应用程序中使用Web API服务时对用户进行身份验证

    This would be the simplest approach, because you would rely on the Authentication in ASP.Net 这将是最简单的方法,因为您将依赖ASP.Net中身份验证

    This is a simple example: 这是一个简单的例子:

    Web.config Web.config文件

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

    Users will be redirected to the account/login route, there you would render custom controls to ask for user credentials and then you would set the authentication cookie using: 用户将被重定向到帐户/登录路由,在那里您将呈现自定义控件以请求用户凭据,然后您将使用以下设置身份验证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); 
  • Cross - platform authentication 跨平台认证

    This case would be when you are only exposing Web API services within the Web application therefore, you would have another client consuming the services, the client could be another Web application or any .Net application (Win Forms, WPF, console, Windows service, etc) 这种情况是当您只在Web应用程序中公开Web API服务时 ,您将有另一个客户端使用服务,客户端可能是另一个Web应用程序或任何.Net应用程序(Win Forms,WPF,控制台,Windows服务,等等)

    For example assume that you will be consuming the Web API service from another web application on the same network domain (within an intranet), in this case you could rely on the Windows authentication provided by ASP.Net. 例如,假设您将从同一网络域(在Intranet中)的另一个Web应用程序中使用Web API服务,在这种情况下,您可以依赖ASP.Net提供的Windows身份验证。

     <authentication mode="Windows" /> 

    If your services are exposed on the Internet, then you would need to pass the authenticated tokens to each Web API service. 如果您的服务在Internet上公开,那么您需要将经过身份验证的令牌传递给每个Web API服务。

    For more info, take a loot to the following articles: 有关更多信息,请获取以下文章的战利品:

If you want to authenticate against a user name and password and without an authorization cookie , the MVC4 Authorize attribute won't work out of the box. 如果要对用户名和密码进行身份验证并且没有授权cookie ,则MVC4 Authorize属性将无法开箱即用。 However, you can add the following helper method to your controller to accept basic authentication headers. 但是,您可以将以下帮助程序方法添加到控制器以接受基本身份验证标头。 Call it from the beginning of your controller's methods. 从控制器的方法开始调用它。

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

From the client side, this helper creates a HttpClient with the authentication header in place: 从客户端,这个助手创建一个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;
}

I am working on a MVC5/Web API project and needed to be able to get authorization for the Web Api methods. 我正在研究MVC5 / Web API项目,并且需要能够获得Web Api方法的授权。 When my index view is first loaded I make a call to the 'token' Web API method which I believe is created automatically. 首次加载我的索引视图时,我调用了'token'Web API方法,我认为该方法是自动创建的。

The client side code (CoffeeScript) to get the token is: 获取令牌的客户端代码(CoffeeScript)是:

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

If successful the following is called, which saves the authentication token locally: 如果成功,则调用以下内容,以在本地保存身份验证令牌:

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

Then if I need to make an Ajax call to a Web API method that has the [Authorize] tag I simply add the following header to my Ajax call: 然后,如果我需要对具有[Authorize]标记的Web API方法进行Ajax调用,我只需将以下标题添加到我的Ajax调用中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM