ASP.NET Web API身份validation
我正在寻找使用ASP.NET Web API在客户端应用程序中对用户进行身份validation。 我已经观看了网站上的所有video,并阅读了此论坛post 。
正确放置[Authorize]
属性将返回401 Unauthorized
状态。 但是,我需要知道如何让用户login到API。
我想从Android应用程序提供用户凭据到API,让用户login,然后所有后续的API调用预先authentication。
允许用户login到API
您需要发送一个有效的表单身份validationcookie连同请求。 这个cookie通常通过调用[FormsAuthentication.SetAuthCookie
方法(参见MSDN )进行身份validation( LogOn
操作)时由服务器发送。
所以客户需要执行2个步骤:
- 通过发送用户名和密码发送一个HTTP请求到
LogOn
操作。 反过来,这个动作将调用FormsAuthentication.SetAuthCookie
方法(如果凭据是有效的),这又将在响应中设置表单身份validationcookie。 - 通过发送第一个请求中检索到的表单身份validationcookie发送HTTP请求到
[Authorize]
受保护的动作。
我们来举个例子。 假设您的Web应用程序中定义了2个API控制器:
第一个负责处理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; } }
第二个包含只有授权用户才能看到的受保护操作:
[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请求在线路上的外观:
authentication请求:
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响应:
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为例。
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设备将本地主机看作自己的主机。 ii。如果在IIS中部署Web API,则必须打开表单身份validation。
使用此代码并访问数据库
[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) }