2012-06-13 63 views
121

Tôi đang tìm cách xác thực người dùng từ ứng dụng khách trong khi sử dụng ASP.NET Web API. Tôi đã xem tất cả các video trên trang web và cũng đọc this forum post.Xác thực API Web ASP.NET

Đặt thuộc tính [Authorize] trả về chính xác trạng thái 401 Unauthorized. Tuy nhiên, tôi cần biết cách cho phép người dùng đăng nhập vào API.

Tôi muốn cung cấp thông tin xác thực người dùng từ ứng dụng Android cho API, giúp người dùng đăng nhập và sau đó có tất cả các cuộc gọi API tiếp theo được xác thực trước.

+0

Hi Mujtaba. Bạn có thể thực hiện việc này không? –

Trả lời

136

cho phép người dùng đăng nhập vào API

Bạn cần phải gửi một cookie hình thức xác thực hợp lệ cùng với yêu cầu. Cookie này thường được máy chủ gửi khi xác thực (LogOn hành động) bằng cách gọi phương thức [FormsAuthentication.SetAuthCookie (xem MSDN).

Vì vậy, khách hàng cần thực hiện 2 bước sau:

  1. Gửi một yêu cầu HTTP đến một hành động LogOn bằng cách gửi tên người dùng và mật khẩu. Lần lượt hành động này sẽ gọi phương thức FormsAuthentication.SetAuthCookie (trong trường hợp thông tin đăng nhập hợp lệ), điều này sẽ lần lượt thiết lập cookie xác thực biểu mẫu trong phản hồi.
  2. Gửi yêu cầu HTTP đến [Authorize] hành động được bảo vệ bằng cách gửi cùng cookie xác thực biểu mẫu mà nó đã truy lục trong yêu cầu đầu tiên.

Hãy lấy một ví dụ. Giả sử rằng bạn có 2 bộ điều khiển API được định nghĩa trong ứng dụng web của bạn:

Đầu tiên một trách nhiệm xử lý xác thực:

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

và điều thứ hai chứa các hành động bảo vệ mà người dùng chỉ được ủy quyền có thể thấy:

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

Bây giờ chúng tôi có thể viết một ứng dụng khách hàng tiêu thụ API này. Dưới đây là một tầm thường ví dụ giao diện điều khiển ứng dụng (chắc chắn rằng bạn đã cài đặt Microsoft.AspNet.WebApi.ClientMicrosoft.Net.Http gói 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"); 
      } 
     } 
    } 
} 

Và dưới đây là cách 2 yêu cầu HTTP nhìn vào dây:

xác thực yêu cầu:

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

Phản hồi xác thực:

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 

Yêu cầu đối với dữ liệu được bảo vệ:

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

đáp ứng cho dữ liệu được bảo vệ:

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" 
+0

Nó sẽ duy trì một phiên cho ứng dụng Android? –

+0

Có điểm nhưng bạn có thể xin vui lòng gửi một mã mẫu cho điểm thứ hai. Cảm ơn câu trả lời của bạn. –

+2

Viết ứng dụng HTTP HTTP là chủ đề cho một câu hỏi khác. Nó không liên quan đến ASP.NET MVC và ASP.NET MVC Web API, đó là câu hỏi của bạn. Tôi khuyên bạn nên bắt đầu một chuỗi mới gắn thẻ rõ ràng với Java và Android, trong đó bạn hỏi về cách viết một máy khách HTTP gửi yêu cầu bằng cách sử dụng cookie. –

12

Tôi lấy android làm ví dụ.

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

Lưu ý: i.localhost không thể sử dụng được. Thiết bị Android nhìn localhost như chính nó lưu trữ. ii.Nếu triển khai API web trong IIS, phải xác thực mẫu.

0

Sử dụng mã và truy cập cơ sở dữ liệu này

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