NET Web API 身份验证

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

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

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

40834 次浏览

allow a user to log in to the API

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

So the client needs to perform 2 steps:

  1. 通过发送用户名和密码向 LogOn操作发送 HTTP 请求。反过来,这个操作将调用 FormsAuthentication.SetAuthCookie方法(在凭据有效的情况下) ,该方法将在响应中设置表单身份验证 cookie。
  2. 通过发送它在第一个请求中检索到的表单身份验证 cookie,向受 [Authorize]保护的操作发送一个 HTTP 请求。

举个例子,假设你在你的 web 应用中定义了两个 API 控制器:

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

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

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

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

现在我们可以编写一个使用这个 API 的客户机应用程序。下面是一个简单的控制台应用例子(确保你已经安装了 Microsoft.AspNet.WebApi.ClientMicrosoft.Net.Http NuGet 软件包) :

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

下面是2个 HTTP 请求在线路上的外观:

认证要求:

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

认证回应:

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

要求保护数据:

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

对受保护数据的响应:

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"

我以机器人为例。

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

请注意: 不能使用 i.localhost。 Android 设备将 localhost 看作自己的主机。 ii.If deploy the web API in IIS, the Form authentication must be opened.

使用此代码并访问数据库

[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)
}