it-swarm.com.de

Anmeldemethode für ASP.NET-Web-API

Ich möchte einen RESTful-Webdienst mit der ASP.NET-Web-API erstellen, den Entwickler von Drittanbietern für den Zugriff auf die Daten meiner Anwendung verwenden. 

In Visual Studio entschied ich mich, ein neues ASP.NET-Projekt zu erstellen. Ich folgte diesem Tutorial , wähle aber eine andere Vorlage: Web-API-Vorlage. Ich verwende eine MySQL-Datenbank mit den Standard-Benutzerrollentabellen, wie im Tutorial erklärt.

Die Vorlage enthält viele sehr interessante Methoden, um einen neuen Benutzer zu registrieren, es gibt jedoch keine Standardanforderung für die Anmeldung. Ich habe das geschrieben, ohne zu verstehen, was ich tue:

    // POST api/Account/Login
    [Route("Login")]
    public IHttpActionResult Login(LoginBindingModel model)
    {
        ClaimsIdentity ci = new ClaimsIdentity();
        // ...
        // ...
        Authentication.SignIn(ci);
        return Ok();
    }

Ich habe viel über Sicherheit gelesen, ohne ein gutes Beispiel mit einer Dokumentation zu finden, die erklärt, wie es funktioniert. Es scheint unglaublich schwierig zu sein, eine einfache Anmeldemethode in der Web-API zu implementieren.

Könnten Sie mir erklären, warum es in dieser Vorlage keine Anmeldemethode gibt? Haben Sie ein Muster der Anmeldemethode? Und was sollte ich zur Authentifizierung der Anfrage an die Clientanwendung zurücksenden? Arbeitet das mit einem Token?

14

Normalerweise implementieren Sie die Anmeldelogik in dieser Methode und geben ein Token zurück, das bei jedem Aufruf an Ihre API validiert wird.

Sie können dies für weitere Informationen lesen

http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

15
dariogriffo

Wenn Sie einen neuen ASP.NET Web Application -> Web API -> Authentifizierung ändern -> Individual User Accounts erstellt haben. Schauen Sie sich App_Start -> Startup.Auth.cs an.

Es sollte so etwas enthalten:

PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/Token"),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
    // In production mode set AllowInsecureHttp = false
    AllowInsecureHttp = true
};

// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);

Das bedeutet, dass Sie eine Anfrage für ein Zugriffstoken senden können, beispielsweise Anfrage:

 enter image description here

Sie können dann überprüfen, ob das Zugriffstoken funktioniert:

 enter image description here

Mit diesem Token können Sie jetzt auf alle geschützten Ressourcen zugreifen, auf die der Benutzer Zugriff hat.

5
Ogglas

Wenn Sie eine API für Entwickler von Drittanbietern erstellen möchten, müssen Sie sie mit OAuth 2.0-Flows absichern. Ich habe einen ausführlichen Beitrag als @dariogriffo geschrieben, der Sie angewiesen hat, den Fluss der Ressourceneigentümerpasswörter zu implementieren, der für Ihren Fall von Nutzen ist.

Sie müssen keinen Endpunkt für die Anmeldung erstellen. Sie müssen die API mithilfe von Owin Middle-Wares konfigurieren, um OAuth-Bearer-Token an die Benutzer auszugeben, wenn Sie einen Endpunkt wie "/ token" aufrufen. Anschließend senden die Benutzer dieses Token weiter zusammen mit jeder Anforderung im Berechtigungsheader. Lesen Sie mehr über diese tokenbasierte Authentifizierung .

4
Taiseer Joudeh

Für andere eine Hilfsklasse, zunächst mit:

namespace WeBAPITest
{



#region Using Statements:



using System.Net.Http;
using System.Collections.Generic;

using Newtonsoft.Json;



#endregion



public class HttpWebApi
{



#region Fields:



private static readonly HttpClient client = new HttpClient();



#endregion



#region Properties:



/// <summary>
/// The basr Uri.
/// </summary>
public string BaseUrl { get; set; }



/// <summary>
/// Username.
/// </summary>
protected internal string Username { get; set; }



/// <summary>
/// Password.
/// </summary>
protected internal string Password { get; set; }



/// <summary>
/// The instance of the Root Object Json Deserialised Class.
/// </summary>
internal Rootobject Authentication { get; set; }



/// <summary>
/// The Access Token from the Json Deserialised Login.
/// </summary>
public string AccessToken { get { return Authentication.access_token; } }



#endregion



public HttpWebApi(string baseurl)
{

    // Init Base Url:
    BaseUrl = baseurl;
}



/// <summary>
/// Get from the Web API.
/// </summary>
/// <param name="path">The BaseUrl + path (Uri.Host + api/Controller) to the Web API.</param>
/// <returns>A Task, when awaited, a string</returns>
public async System.Threading.Tasks.Task<string> Get(string path)
{

    if (Authentication.access_token == null)
    throw new System.Exception("Authentication is not completed.");

    // GET
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Authentication.access_token);
    return await client.GetStringAsync(BaseUrl + path);
}



/// <summary>
/// Logs In and populates the Authentication Variables.
/// </summary>
/// <param name="username">Your Username</param>
/// <param name="password">Your Password</param>
/// <returns>A Task, when awaited, a string</returns>
public async System.Threading.Tasks.Task<string> Login(string username, string password)
{

    // Set Username:
    Username = username;

    // Set Password:
    Password = password;

    // Conf String to Post:
    var Dic = new Dictionary<string, string>() { { "grant_type", "password" }, { "username", "" }, { "password", "" } };
    Dic["username"] = username;
    Dic["password"] = password;

    // Post to Controller:
    string auth = await Post("/Token", Dic);

    // Deserialise Response:
    Authentication = JsonConvert.DeserializeObject<Rootobject>(auth);

    return auth;
}



/// <summary>
/// Post to the Web API.
/// </summary>
/// <param name="path">The BaseUrl + path (Uri.Host + api/Controller) to the Web API.</param>
/// <param name="values">The new Dictionary<string, string> { { "value1", "x" }, { "value2", "y" } }</param>
/// <returns>A Task, when awaited, a string</returns>
public async System.Threading.Tasks.Task<string> Post(string path, Dictionary<string, string> values)
{

    // Add Access Token to the Headder:
    if (Authentication != null)
    if (Authentication.access_token != "")
        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Authentication.access_token);

    // Encode Values:
    var content = new FormUrlEncodedContent(values);

    // Post and get Response:
    var response = await client.PostAsync(BaseUrl + path, content);

    // Return Response:
    return await response.Content.ReadAsStringAsync();
}



/// <summary>
/// Register a new User.
/// </summary>
/// <param name="username">Your Username, E-Mail</param>
/// <param name="password">Your Password</param>
/// <returns>A Task, when awaited, a string</returns>
public async System.Threading.Tasks.Task<string> Register(string username, string password)
{

    // Register: api/Account/Register
    var Dic = new Dictionary<string, string>() { { "Email", "" }, { "Password", "" }, { "ConfirmPassword", "" } };
    Dic["Email"] = username;
    Dic["Password"] = password;
    Dic["ConfirmPassword"] = password;

    return await Post("api/Account/Register", Dic);
}
}



/// <summary>
/// For Json Deserialisation.
/// </summary>
internal class Rootobject
{

/// <summary>
/// The Web Api Access Token. Gets added to the Header in each communication.
/// </summary>
public string access_token { get; set; }



/// <summary>
/// The Token Type
/// </summary>
public string token_type { get; set; }



/// <summary>
/// Expiry.
/// </summary>
public int expires_in { get; set; }



/// <summary>
/// The Username.
/// </summary>
public string userName { get; set; }



/// <summary>
/// Issued.
/// </summary>
public string issued { get; set; }



/// <summary>
/// Expiry.
/// </summary>
public string expires { get; set; }
}
}

Speziell für die standardmäßige, unbearbeitete Web-API-Vorlage in Visual Studio konzipiert.

Dann:

HttpWebApi httpWebApi = new HttpWebApi("http://localhost/");
await httpWebApi.Login("email", "password");

richTextBox1.AppendText(await httpWebApi.Get("api/Account/UserInfo") + Environment.NewLine);

Hoffe das hilft anderen einigen!

0
Rusty Nail