2014-10-22 36 views
12

Ich möchte einen RESTful-Webdienst mithilfe der ASP.NET-Web-API erstellen, die von Drittentwicklern für den Zugriff auf die Daten meiner Anwendung verwendet wird.ASP.NET Web API Anmeldemethode

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

Die Vorlage enthält viele sehr interessante Methoden, um einen neuen Benutzer zu registrieren, aber es gibt keine Standard-Login-Anfrage. Ich schrieb dies, 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 ziemlich viel über Sicherheit gelesen habe, ohne eine gute Probe mit der Dokumentation zu finden, zu erklären, wie es funktioniert. Es scheint unglaublich schwierig zu sein, eine einfache Login-Methode in der Web-API zu implementieren.

Können Sie mir erklären, warum es in dieser Vorlage keine Login-Methode gibt. Haben Sie ein Beispiel für die Login-Methode? Und was soll ich zurück an die Client-Anwendung senden, um die Anfrage zu authentifizieren. Funktioniert das mit einem Token?

+0

vielleicht hilft Ihnen dieser Artikel http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api – Monah

+2

Dieser Artikel ist das perfekte Beispiel für minimalistische Dokumentation über das Thema. –

Antwort

13

In der Regel, was Sie tun, ist die Login-Logik in dieser Methode zu implementieren, und ein Token zurückgeben, die dann bei jedem Aufruf an Ihre API validiert werden.

Sie diese für weitere Informationen lesen können

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

+7

Eigentlich habe ich nach dem Lesen Ihres Artikels festgestellt, dass es keine Login-Methode gibt, weil Microsoft sich entschieden hat, Token (wieder) zu benennen. Siehe ConfigureAuth-Methode in startup.cs –

4

Wenn Sie eine API für Drittentwickler bauen wollen, dann müssen Sie sichern OAuth 2.0 Ströme verwendet wird, habe ich detaillierte Post geschrieben als @dariogriffo wies Sie an, welche den Ressourceneignerpasswortberechtigungsfluss implementiert, der für Ihren Fall gut ist.

Sie müssen keinen Endpunkt für die Anmeldung erstellen. Sie konfigurieren die API mit Owin-Middleware, um den Benutzern OAuth-Bearer-Token auszugeben, wenn sie einen Endpunkt wie "/ token" und dann die Benutzer aufrufen Senden Sie dieses Token zusammen mit jeder Anfrage im Autorisierungsheader. Lesen Sie mehr dazu token based authentication.

4

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

Es sollte wie folgt 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); 

Dies bedeutet, dass Sie eine Anfrage für ein Zugriffstoken senden, zB Anfrage:

enter image description here

Sie können dann sicher, dass der Zugang Token Werke:

enter image description here

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

0

für andere, eine Hilfsklasse, beginnen 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; } 
} 
} 

Besonders für den Standard entworfen, ungeschnittenes Web Api Vorlage in Visual Studio.

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 einige!