2012-06-13 9 views
121

Szukam uwierzytelnienia użytkownika z aplikacji klienta podczas korzystania z ASP.NET Web API. Oglądałem wszystkie filmy na stronie, a także czytałem this forum post.Uwierzytelnianie ASP.NET Web API

Umieszczenie atrybutu [Authorize] poprawnie zwraca status 401 Unauthorized. Jednak muszę wiedzieć, jak zezwolić użytkownikowi na logowanie się do interfejsu API.

Chcę podać dane uwierzytelniające użytkownika z aplikacji systemu Android do interfejsu API, uzyskać logowanie użytkownika, a następnie wstępnie uwierzytelnić wszystkie kolejne wywołania interfejsu API.

+0

Hi Mujtaba. Czy byłeś w stanie to wdrożyć? –

Odpowiedz

136

umożliwić użytkownikowi zalogować się do interfejsu API

Musisz wysłać poprawny plik cookie uwierzytelniania formularza wraz z wnioskiem. Ten plik cookie jest zwykle wysyłany przez serwer podczas uwierzytelniania (LogOn) przez wywołanie metody [FormsAuthentication.SetAuthCookie (patrz MSDN).

więc klient musi wykonać 2 czynności:

  1. wysłać żądanie HTTP do LogOn działania wysyłając nazwę użytkownika i hasło. Po kolei ta akcja wywoła metodę FormsAuthentication.SetAuthCookie (w przypadku, gdy poświadczenia są prawidłowe), która z kolei ustawi plik cookie uwierzytelniania formularzy w odpowiedzi.
  2. Wysyła żądanie HTTP do chronionej akcji [Authorize], wysyłając plik cookie uwierzytelniania formularzy pobrany w pierwszym żądaniu.

Weźmy przykład. Załóżmy, że masz 2 kontrolery API zdefiniowane w aplikacji Web:

Pierwszy z nich odpowiedzialny za uwierzytelnianie magazynowe:

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

a drugi zawiera chronione akcje, że tylko autoryzowani użytkownicy mogą widzieć:

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

Teraz możemy napisać aplikację kliencką korzystającą z tego interfejsu API. Oto trywialny przykład aplikacja konsoli (upewnij się, że masz zainstalowane pakiety Microsoft.AspNet.WebApi.Client i 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"); 
      } 
     } 
    } 
} 

A oto jak żądania HTTP 2 spojrzeć na drucie: Prośba

Uwierzytelnianie:

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

Uwierzytelnianie:

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 

Zapytanie o chronionych danych:

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

Reakcja na dane chronione:

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

Czy utrzyma się sesja dla aplikacji na Androida? –

+0

Masz rację, ale możesz wysłać przykładowy kod do drugiego punktu. Dzięki za odpowiedź. –

+2

Pisanie klienta HTTP Androida jest przedmiotem innego pytania. Nie ma związku z ASP.NET MVC i ASP.NET MVC Web API, o to właśnie chodziło Twoje pytanie. Polecam rozpocząć nowy wątek jednoznacznie tagując Java i Android, w którym pytasz o to, jak napisać klienta HTTP, który wysyła żądania za pomocą plików cookie. –

12

biorę androida jako przykład.

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

Uwaga proszę: i.localhost nie może być używany. Urządzenie z systemem Android wygląda jak host localhosta. ii. W przypadku wdrażania interfejsu API WWW w IIS należy otworzyć uwierzytelnianie formularza.

0

Użyj tego kodu, a dostęp do bazy danych

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