ASP.NET Web API 身份验证
Posted
技术标签:
【中文标题】ASP.NET Web API 身份验证【英文标题】:ASP.NET Web API Authentication 【发布时间】:2012-06-16 09:57:48 【问题描述】:我希望在使用 ASP.NET Web API 时从客户端应用程序验证用户。我已经观看了网站上的所有视频并阅读了this forum post。
正确放置[Authorize]
属性会返回401 Unauthorized
状态。但是,我需要知道如何允许用户登录 API。
我想从 android 应用程序向 API 提供用户凭据,让用户登录,然后对所有后续 API 调用进行预身份验证。
【问题讨论】:
嗨 Mujtaba。你能实现这个吗? 首先使用 CORS 来防止来自其他域的不必要的攻击。然后随请求一起发送一个有效的 Forms Authentication cookie,最后通过令牌授权请求。这种组合始终使您的 web api 安全和优化。 【参考方案1】:允许用户登录 API
您需要随请求一起发送有效的表单身份验证 cookie。该 cookie 通常由服务器在通过调用[FormsAuthentication.SetAuthCookie
方法进行身份验证(LogOn
操作)时发送(参见MSDN)。
所以客户端需要执行2个步骤:
-
通过发送用户名和密码向
LogOn
操作发送HTTP 请求。反过来,此操作将调用 FormsAuthentication.SetAuthCookie
方法(如果凭据有效),该方法又会在响应中设置表单身份验证 cookie。
通过发送在第一个请求中检索到的表单身份验证 cookie,向受 [Authorize]
保护的操作发送 HTTP 请求。
让我们举个例子。假设您在 Web 应用程序中定义了 2 个 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.Client
和 Microsoft.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"
【讨论】:
它会为 Android 应用程序维护一个会话吗? 明白了,但能否请您发布第二点的示例代码。谢谢你的回答。 编写 Android HTTP 客户端是另一个问题的主题。它与您的问题所在的 ASP.NET MVC 和 ASP.NET MVC Web API 无关。我建议您启动一个使用 Java 和 Android 显式标记的新线程,在其中询问如何编写使用 cookie 发送请求的 HTTP 客户端。 实际上,在 MVC4 WebApi 的文献中,他们已经写到 WebAPI 是第三方客户端特别是移动客户端的目标(当然是)。假设我们有一个桌面应用程序客户端,请您发布一个简单的代码 sn-p。谢谢 另请参阅有关使用 HTTP 基本身份验证的问题(和答案):***.com/questions/10987455/…【参考方案2】:我以安卓为例。
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.如果在IIS中部署Web API,必须开启Form认证。
【讨论】:
【参考方案3】:使用此代码并访问数据库
[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)
【讨论】:
以上是关于ASP.NET Web API 身份验证的主要内容,如果未能解决你的问题,请参考以下文章
ASP.net Web API RESTful Web 服务 + 基本身份验证