ASP.NET-Web-API-Authentifizierung

122

Ich möchte einen Benutzer von einer Clientanwendung aus authentifizieren, während ich die ASP.NET-Web-API verwende . Ich habe alle Videos auf der Website gesehen und auch diesen Forumsbeitrag gelesen .

Wenn Sie das [Authorize]Attribut richtig setzen, wird ein 401 UnauthorizedStatus zurückgegeben. Ich muss jedoch wissen, wie ein Benutzer sich bei der API anmelden kann.

Ich möchte der API Benutzeranmeldeinformationen aus einer Android-Anwendung bereitstellen, den Benutzer anmelden und dann alle nachfolgenden API-Aufrufe vorauthentifizieren lassen.

Mujtaba Hassan
quelle
Hallo Mujtaba. Konnten Sie dies umsetzen?
Vivek Chandraprakash
Verwenden Sie zuerst CORS, um unerwünschte Treffer von anderen Domänen zu verhindern. Senden Sie dann zusammen mit der Anfrage ein gültiges Formularauthentifizierungs-Cookie und autorisieren Sie die Anfrage schließlich per Token. Diese Kombination macht Ihre Web-API immer sicher und optimiert.
Majedur Rahaman

Antworten:

137

Ermöglichen Sie einem Benutzer, sich bei der API anzumelden

Sie müssen zusammen mit der Anfrage ein gültiges Formularauthentifizierungs-Cookie senden. Dieses Cookie wird normalerweise vom Server bei der Authentifizierung ( LogOnAktion) durch Aufrufen der [FormsAuthentication.SetAuthCookieMethode gesendet (siehe MSDN ).

Der Client muss also zwei Schritte ausführen:

  1. Senden Sie eine HTTP-Anfrage an eine LogOnAktion, indem Sie den Benutzernamen und das Passwort senden. Diese Aktion ruft abwechselnd die FormsAuthentication.SetAuthCookieMethode auf (falls die Anmeldeinformationen gültig sind), die wiederum das Formularauthentifizierungscookie in der Antwort setzt.
  2. Senden Sie eine HTTP-Anforderung an eine [Authorize]geschützte Aktion, indem Sie das Formularauthentifizierungs-Cookie senden, das in der ersten Anforderung abgerufen wurde.

Nehmen wir ein Beispiel. Angenommen, in Ihrer Webanwendung sind zwei API-Controller definiert:

Der erste, der für die Authentifizierung verantwortlich ist:

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

und die zweite enthält geschützte Aktionen, die nur autorisierte Benutzer sehen können:

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

Jetzt könnten wir eine Client-Anwendung schreiben, die diese API verwendet. Hier ist ein einfaches Anwendungsbeispiel für eine Konsole (stellen Sie sicher, dass Sie die Pakete Microsoft.AspNet.WebApi.Clientund Microsoft.Net.HttpNuGet installiert haben ):

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

Und so sehen die 2 HTTP-Anforderungen auf dem Draht aus:

Authentifizierungsanforderung:

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

Authentifizierungsantwort:

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

Anfrage für geschützte Daten:

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

Antwort für geschützte Daten:

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"
Darin Dimitrov
quelle
Wird eine Sitzung für die Android-Anwendung beibehalten?
Mujtaba Hassan
Ich habe den Punkt verstanden, aber können Sie bitte einen Beispielcode für den zweiten Punkt posten? Danke für deine Antwort.
Mujtaba Hassan
2
Das Schreiben eines Android-HTTP-Clients ist ein Thema für eine andere Frage. Es hat nichts mit ASP.NET MVC und ASP.NET MVC Web API zu tun, worum es in Ihrer Frage ging. Ich würde empfehlen, einen neuen Thread zu starten, der explizit mit Java und Android markiert ist und in dem Sie gefragt werden, wie ein HTTP-Client geschrieben werden soll, der Anforderungen mithilfe von Cookies sendet.
Darin Dimitrov
Tatsächlich haben sie in der Literatur von MVC4 WebApi geschrieben, dass WebAPI ein Ziel für Drittanbieter-Clients ist, insbesondere für mobile Clients (und natürlich auch für Clients). Nehmen wir an, wir haben einen Desktop-Anwendungsclient. Können Sie bitte ein einfaches Code-Snippet veröffentlichen? Vielen Dank
Mujtaba Hassan
2
Siehe auch diese Frage (und Antwort) zur Verwendung der HTTP-Basisauthentifizierung: stackoverflow.com/questions/10987455/…
Jim Harte
12

Ich nehme Android als Beispiel.

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

Achtung bitte: i.localhost kann nicht verwendet werden. Android-Gerät sieht localhost als selbst Host. ii.Wenn die Web-API in IIS bereitgestellt wird, muss die Formularauthentifizierung geöffnet werden.

user2293998
quelle
0

Verwenden Sie diesen Code und greifen Sie auf die Datenbank zu

[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) 
}
Sanila Salim
quelle