2012-06-13 39 views
121

ASP.NET Web APIを使用しているときにクライアントアプリケーションからユーザーを認証しようとしています。私はサイトのすべての動画を見て、this forum postも読んでいます。ASP.NET Web API認証

[Authorize]属性を正しく設定すると、401 Unauthorizedステータスが正しく返されます。しかし、ユーザーにAPIへのログインを許可する方法を知っておく必要があります。

私はAndroidアプリケーションからAPIにユーザーの資格情報を提供し、ログインしたユーザーを取得し、その後のすべてのAPIコールを事前認証する必要があります。

+0

こんにちはMujtaba。これを実装できましたか? –

答えて

136

ユーザーがAPI

にログインすることができますあなたは、要求と一緒に、有効なフォーム認証Cookieを送信する必要があります。このクッキーは、通常[FormsAuthentication.SetAuthCookieメソッド(MSDNを参照)を呼び出すことによって認証(LogOnアクション)するとサーバーから送信されます。

だから、クライアントは2つのステップを実行する必要があります。

  1. をユーザー名とパスワードを送信することにより、LogOnアクションにHTTPリクエストを送信します。このアクションでは、FormsAuthentication.SetAuthCookieメソッド(資格情報が有効な場合)が呼び出され、レスポンスにフォーム認証Cookieが設定されます。
  2. 最初の要求で取得したフォーム認証Cookieを送信することによって、保護された処理にHTTP要求を送信します。

例を挙げておきます。あなたのWebアプリケーションで定義された2 APIコントローラがあるとします。

認証を処理するための責任が最初の1:

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

と、許可されたユーザーのみが見ることができる保護されたアクションを含む第二1:

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

このAPIを使用するクライアントアプリケーションを作成できました。ここでは(あなたがMicrosoft.AspNet.WebApi.ClientMicrosoft.Net.Http NuGetパッケージをインストールしていることを確認してください)些細なコンソールアプリケーションの例です:

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

そして、ここでは2件のHTTPリクエストがワイヤ上に見える方法は次のとおりです。

認証要求:

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

認証応答:

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 
保護されたデータのための0

要求:保護されたデータのための

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

は応答:

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" 
+0

Androidアプリケーションのセッションを維持する予定ですか? –

+0

ポイントを獲得しましたが、2番目のポイントのサンプルコードを投稿してください。ご回答有難うございます。 –

+2

Android HTTPクライアントを書くことは別の質問の対象です。あなたの質問については、ASP.NET MVCとASP.NET MVC Web APIとは無関係です。 JavaとAndroidで明示的にタグ付けする新しいスレッドを開始することをお勧めします。このスレッドでは、Cookieを使用してリクエストを送信するHTTPクライアントを作成する方法を尋ねます。 –

12

私は例として、アンドロイドを取ります。

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

注意してください: i.localhostを使用することはできません。 Androidデバイスは、自分自身のホストとしてlocalhostを見ます。 ii。IISでWeb APIをデプロイする場合は、フォーム認証を開く必要があります。

0

使用このコードとアクセスデータベース

[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) 
} 
関連する問題