Android ASP.NET Web API 身份验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11014953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:44:32  来源:igfitidea点击:

ASP.NET Web API Authentication

android.netauthenticationasp.net-web-api

提问by Mujtaba Hassan

I am looking to authenticate a user from a client application while using the ASP.NET Web API. I have watched all the videos on the site and also read this forum post.

我希望在使用ASP.NET Web API时从客户端应用程序对用户进行身份验证。我已经观看了网站上的所有视频,也阅读了这个论坛帖子

Putting the [Authorize]attribute correctly returns a 401 Unauthorizedstatus. However, I need to know how to allow a user to log in to the API.

[Authorize]正确放置属性会返回一个401 Unauthorized状态。但是,我需要知道如何允许用户登录 API。

I want to provide user credentials from an Android application to the API, get the user logged in, and then have all subsequent API calls pre-authenticated.

我想从 Android 应用程序向 API 提供用户凭据,让用户登录,然后对所有后续 API 调用进行预身份验证。

回答by Darin Dimitrov

allow a user to log in to the API

允许用户登录 API

You need to send a valid Forms Authentication cookie along with the request. This cookie is usually sent by the server when authenticating (LogOnaction) by calling the [FormsAuthentication.SetAuthCookiemethod (see MSDN).

您需要随请求一起发送有效的表单身份验证 cookie。此 cookie 通常由服务器在LogOn通过调用[FormsAuthentication.SetAuthCookie方法进行身份验证(操作)时发送(参见MSDN)。

So the client needs to perform 2 steps:

所以客户端需要执行2个步骤:

  1. Send an HTTP request to a LogOnaction by sending the username and password. In turns this action will call the FormsAuthentication.SetAuthCookiemethod (in case the credentials are valid) which in turn will set the forms authentication cookie in the response.
  2. Send an HTTP request to an [Authorize]protected action by sending along the forms authentication cookie it retrieved in the first request.
  1. LogOn通过发送用户名和密码向操作发送 HTTP 请求。反过来,此操作将调用该FormsAuthentication.SetAuthCookie方法(如果凭据有效),该方法又将在响应中设置表单身份验证 cookie。
  2. [Authorize]通过发送它在第一个请求中检索到的表单身份验证 cookie,将HTTP 请求发送到受保护的操作。

Let's take an example. Suppose that you have 2 API controllers defined in your web application:

让我们举个例子。假设您在 Web 应用程序中定义了 2 个 API 控制器:

The first one responsible for handling authentication:

第一个负责处理身份验证:

public class AccountController : ApiController
{
    public bool Post(LogOnModel model)
    {
        if (model.Username == "john" && model.Password == "secret")
        {
            FormsAuthentication.SetAuthCookie(model.Username, false);
            return true;
        }

        return false;
    }
}

and the second one containing protected actions that only authorized users can see:

第二个包含只有授权用户才能看到的受保护操作:

[Authorize]
public class UsersController : ApiController
{
    public string Get()
    {
        return "This is a top secret material that only authorized users can see";
    }
}

Now we could write a client application consuming this API. Here's a trivial console application example (make sure you have installed the Microsoft.AspNet.WebApi.Clientand Microsoft.Net.HttpNuGet packages):

现在我们可以编写一个使用这个 API 的客户端应用程序。这是一个简单的控制台应用程序示例(确保您已安装Microsoft.AspNet.WebApi.ClientMicrosoft.Net.HttpNuGet 包):

using System;
using System.Net.Http;
using System.Threading;

class Program
{
    static void Main()
    {
        using (var httpClient = new HttpClient())
        {
            var response = httpClient.PostAsJsonAsync(
                "http://localhost:26845/api/account", 
                new { username = "john", password = "secret" }, 
                CancellationToken.None
            ).Result;
            response.EnsureSuccessStatusCode();

            bool success = response.Content.ReadAsAsync<bool>().Result;
            if (success)
            {
                var secret = httpClient.GetStringAsync("http://localhost:26845/api/users");
                Console.WriteLine(secret.Result);
            }
            else
            {
                Console.WriteLine("Sorry you provided wrong credentials");
            }
        }
    }
}

And here's how the 2 HTTP requests look on the wire:

以下是 2 个 HTTP 请求在网络上的外观:

Authentication request:

认证请求:

POST /api/account HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: localhost:26845
Content-Length: 39
Connection: Keep-Alive

{"username":"john","password":"secret"}

Authentication response:

认证响应:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 13 Jun 2012 13:24:41 GMT
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=REMOVED FOR BREVITY; path=/; HttpOnly
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json; charset=utf-8
Content-Length: 4
Connection: Close

true

Request for protected data:

请求保护数据:

GET /api/users HTTP/1.1
Host: localhost:26845
Cookie: .ASPXAUTH=REMOVED FOR BREVITY

Response for protected data:

对受保护数据的响应:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 13 Jun 2012 13:24:41 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json; charset=utf-8
Content-Length: 66
Connection: Close

"This is a top secret material that only authorized users can see"

回答by user2293998

I take android as example.

我以安卓为例。

public abstract class HttpHelper {

private final static String TAG = "HttpHelper";
private final static String API_URL = "http://your.url/api/";

private static CookieStore sCookieStore;

public static String invokePost(String action, List<NameValuePair> params) {
    try {
        String url = API_URL + action + "/";
        Log.d(TAG, "url is" + url);
        HttpPost httpPost = new HttpPost(url);
        if (params != null && params.size() > 0) {
            HttpEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
            httpPost.setEntity(entity);
        }
        return invoke(httpPost);
    } catch (Exception e) {
        Log.e(TAG, e.toString());
    }

    return null;
}

public static String invokePost(String action) {
    return invokePost(action, null);
}

public static String invokeGet(String action, List<NameValuePair> params) {
    try {
        StringBuilder sb = new StringBuilder(API_URL);
        sb.append(action);
        if (params != null) {
            for (NameValuePair param : params) {
                sb.append("?");
                sb.append(param.getName());
                sb.append("=");
                sb.append(param.getValue());
            }
        }
        Log.d(TAG, "url is" + sb.toString());
        HttpGet httpGet = new HttpGet(sb.toString());
        return invoke(httpGet);
    } catch (Exception e) {
        Log.e(TAG, e.toString());
    }

    return null;
}

public static String invokeGet(String action) {
    return invokeGet(action, null);
}

private static String invoke(HttpUriRequest request)
        throws ClientProtocolException, IOException {
    String result = null;
    DefaultHttpClient httpClient = new DefaultHttpClient();

    // restore cookie
    if (sCookieStore != null) {
        httpClient.setCookieStore(sCookieStore);
    }

    HttpResponse response = httpClient.execute(request);

    StringBuilder builder = new StringBuilder();
    BufferedReader reader = new BufferedReader(new InputStreamReader(
            response.getEntity().getContent()));
    for (String s = reader.readLine(); s != null; s = reader.readLine()) {
        builder.append(s);
    }
    result = builder.toString();
    Log.d(TAG, "result is ( " + result + " )");

    // store cookie
    sCookieStore = ((AbstractHttpClient) httpClient).getCookieStore();
    return result;
}

Attention please: i.localhost cannot be used. Android device look localhost as itself host. ii.If deploy the web API in IIS, the Form authentication must be opened.

请注意: i.localhost 不能使用。Android 设备将本地主机视为自己的主机。ii.如果在IIS中部署web API,必须开启Form认证。

回答by Sanila Salim

Use this code and access database

使用此代码并访问数据库

[HttpPost]
[Route("login")]
public IHttpActionResult Login(LoginRequest request)
{
       CheckModelState();
       ApiResponse<LoginApiResponse> response = new ApiResponse<LoginApiResponse>();
       LoginResponse user;
       var count = 0;
       RoleName roleName = new RoleName();
       using (var authManager = InspectorBusinessFacade.GetAuthManagerInstance())
       {
           user = authManager.Authenticate(request); 
       } reponse(ok) 
}