2014-10-22 4 views
12

타사 개발자가 내 응용 프로그램 데이터에 액세스하는 데 사용할 ASP.NET 웹 API를 사용하여 RESTful 웹 서비스를 만들고 싶습니다.ASP.NET 웹 API 로그인 방법

Visual Studio에서 새 ASP.NET 프로젝트를 만들기로 결정했습니다. 나는 이것을 tutorial에 따라했지만 다른 템플릿을 선택합니다 : Web API 템플릿. 튜토리얼에서 설명한대로 표준 사용자 롤 테이블과 함께 MySQL 데이터베이스를 사용합니다.

템플릿에는 새로운 사용자를 등록하는 많은 흥미로운 방법이 있지만 기본 로그인 요청은 없습니다. 내가 뭘하는지 이해하지 않고 쓴 : 나는 문서가 어떻게 작동하는지 설명과 함께 좋은 샘플을 발견하지 않고 보안에 대해 꽤 많이 읽었습니다

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

. 웹 API에서 간단한 로그인 메소드를 구현하는 것은 엄청나게 어렵습니다.

이 템플릿에 로그인 방법이없는 이유를 설명해 주시겠습니까? 로그인 방법의 샘플이 있습니까? 요청을 인증하기 위해 클라이언트 응용 프로그램에 무엇을 다시 보내야합니까? 토큰으로 작동합니까?

+0

아마도이 기사는 도움이 될 것입니다. http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api – Monah

+2

이 기사는 주제에 관한 최소한의 문서화의 완벽한 예입니다. –

답변

13

일반적으로 당신이하는 일은 그 메소드에 로그인 로직을 구현하고, API를 호출 할 때마다 유효성을 검사 할 토큰을 반환하는 것입니다.

당신은

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

+7

사실 저는 기사를 읽은 후 Microsoft가 토큰 이름을 변경하기로 결정했기 때문에 로그인 방법이 없다는 것을 발견했습니다. startup.cs에서 ConfigureAuth 메소드를 참조하십시오. –

4

당신이 써드 파티 개발자를위한 API를 구축하기 위하여려고하는 경우는 다음의 OAuth 2.0 흐름을 사용하여 고정 할 필요 자세한 내용은이를 읽을 수있는, 내가 상세한 게시물을 작성했습니다 @dariogriffo는 당신에게 유리한 리소스 소유자 암호 자격 증명 흐름을 구현하는 사용자를 안내합니다.

로그인 할 때 끝점을 만들 필요가 없으며 "/ token"과 같은 끝점을 호출 할 때 Owin 중간 가재를 사용하여 API를 구성하여 사용자에게 OAuth 베어러 토큰을 발급 한 다음 사용자 Authorization 헤더의 각 요청과 함께이 토큰을 계속 보냅니다. 이 token based authentication에 대해 자세히 알아보십시오.

4

ASP.NET Web Application ->Web API -> 변경 인증 ->Individual User Accounts을 새로 작성한 경우. App_Start ->Startup.Auth.cs을 확인하십시오.

그것은이 같은 것을 포함해야한다는 :

enter image description here

당신은 다음 액세스를 확인할 수 있습니다 :

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

이것은 당신이 액세스 토큰, 예를 들어 요청을 요청을 보낼 수 있다는 것을 의미한다 토큰 작동 :

enter image description here

이 토큰을 사용하면 사용자가 액세스 할 수있는 모든 보호 된 리소스에 액세스 할 수 있습니다.

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

는 특히 Visual Studio에서 기본, 편집되지 않은 웹 API 광고 템플릿을 위해 설계 : 다른 사람, 헬퍼 클래스에 대한

0

를 시작합니다.그런 다음

는 :

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

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

희망이 다른 어떤 도움이!