2014-10-22 24 views
12

Tôi muốn xây dựng một dịch vụ web RESTful bằng ASP.NET Web API mà các nhà phát triển bên thứ ba sẽ sử dụng để truy cập dữ liệu của ứng dụng của tôi.Phương pháp đăng nhập ASP.NET Web API

Trong Visual Studio, tôi quyết định tạo một dự án ASP.NET mới. Tôi đã theo dõi số tutorial này nhưng tôi chọn một mẫu khác: mẫu API Web. Tôi sử dụng cơ sở dữ liệu MySQL với các bảng vai trò người dùng chuẩn như được giải thích trong hướng dẫn.

Mẫu đi kèm với nhiều phương pháp rất thú vị để đăng ký người dùng mới nhưng không có yêu cầu Đăng nhập mặc định. Tôi đã viết điều này mà không hiểu những gì tôi đang làm:

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

Tôi đã đọc rất nhiều về bảo mật mà không tìm mẫu tốt với tài liệu giải thích cách hoạt động. Nó có vẻ là vô cùng khó khăn để thực hiện một phương pháp đăng nhập đơn giản trong Web API.

Bạn có thể giải thích cho tôi tại sao không có phương thức đăng nhập nào trong mẫu này hay không. Bạn có mẫu phương thức đăng nhập không. Và tôi nên gửi lại cho ứng dụng khách để xác thực yêu cầu. Điều này có hoạt động với mã thông báo không?

+0

có thể bài viết này sẽ giúp bạn http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api – Monah

+2

Bài viết này là ví dụ hoàn hảo về tài liệu tối giản về chủ đề. –

Trả lời

13

Thông thường những gì bạn làm là triển khai logic đăng nhập trong phương thức đó và trả lại mã thông báo sau đó sẽ được xác thực trên mỗi cuộc gọi đến api của bạn.

Bạn có thể đọc này để biết thêm thông tin

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

+7

Trên thực tế sau khi đọc bài viết của bạn, tôi phát hiện ra không có phương pháp đăng nhập vì Microsoft đã quyết định (lại) đặt tên là Token. Xem phương thức ConfigureAuth trong startup.cs –

4

Nếu bạn đang đi để xây dựng một API cho các nhà phát triển bên thứ ba thì bạn cần phải đảm bảo nó sử dụng dòng OAuth 2.0, tôi đã viết bài chi tiết như @dariogriffo hướng dẫn bạn triển khai luồng thông tin đăng nhập mật khẩu của chủ sở hữu tài nguyên phù hợp với trường hợp của bạn.

Bạn không cần phải tạo điểm kết thúc để đăng nhập, bạn sẽ định cấu hình API bằng cách sử dụng Owin middle wares để phát hành mã thông báo mang OAuth cho người dùng khi gọi đến điểm kết thúc như "/ token" và sau đó là người dùng tiếp tục gửi mã thông báo này cùng với mỗi yêu cầu trong tiêu đề Cấp quyền. Đọc thêm về điều này token based authentication.

4

Nếu bạn đã tạo ASP.NET Web Application mới ->Web API -> Thay đổi xác thực ->Individual User Accounts. Hãy xem App_Start ->Startup.Auth.cs.

Nó nên chứa một cái gì đó như thế này:

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

Điều này có nghĩa rằng bạn có thể gửi một yêu cầu cho một thẻ truy cập, ví dụ yêu cầu:

enter image description here

Sau đó bạn có thể xác minh rằng việc tiếp cận mã thông báo hoạt động:

enter image description here

Với mã thông báo này, bây giờ bạn có thể truy cập tất cả các tài nguyên được bảo vệ mà người dùng có quyền truy cập.

0

Đối với người khác, một lớp helper, để bắt đầu với:

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

thiết kế Riêng đối với mặc định, chưa được chỉnh sửa Web Api Template trong Visual Studio.

Sau đó:

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

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

Hy vọng điều này giúp những người khác một số!

Các vấn đề liên quan