2

私は ASP.Net WebApi で承認がどのように機能するかを学んでおり、別の投稿 ( ASP.NET Web API Authentication ) で Darin Dimitrov による回答に出会いました。なぜ 401 を取得しているのかを理解するのに助けが必要です。

Darin のコードに従って、WebApi プロジェクトを作成し、次のコントローラーとモデルを追加しました。

AccountController.cs

using System.Web.Http;
using System.Web.Security;
using AuthTest.Models;

namespace AuthTest.Controllers
{
    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;
        }
    }
}

ユーザーコントローラー.cs

using System.Web.Http;

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

LogOnModel.cs

namespace AuthTest.Models
{
    public class LogOnModel
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

テスト用に、2 つのボタンと 1 つのラベルを持つ Web フォーム アプリを作成しました。

Default.aspx.cs

using System;
using System.Net.Http;
using System.Threading;

namespace AuthTestWebForms
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void ButtonAuthorizeClick(object sender, EventArgs e)
        {
            using (var httpClient = new HttpClient())
            {
                var response = httpClient.PostAsJsonAsync(
                    "http://localhost/authtest/api/account",
                    new { username = "john", password = "secret" },
                    CancellationToken.None
                ).Result;
                response.EnsureSuccessStatusCode();

                bool success = response.Content.ReadAsAsync<bool>().Result;
                if (success)
                {
                    //LabelResponse.Text = @"Credentials provided";
                    var secret = httpClient.GetStringAsync("http://localhost/authtest/api/users");
                    LabelResponse.Text = secret.Result;
                }
                else
                {
                    LabelResponse.Text = @"Sorry, you provided the wrong credentials";
                }
            }
        }

        protected void ButtonTestAuthClick(object sender, EventArgs e)
        {
            using (var httpClient = new HttpClient())
            {
                var secret = httpClient.GetStringAsync("http://localhost/authtest/api/users");
                LabelResponse.Text = secret.Result;
            }
        }
    }
}

ボタンをクリックして ButtonAuthorizeClick() を実行すると、 Account のコントローラーが起動され、次に Users のコントローラーが起動され、すべて問題ありません。

次に ButtonTestAuthClick() をクリックすると、401 (Unauthorized) エラーが発生します。

Chrome または FireFox で ASPXAUTH Cookie を探しても見つからないため、ButtonAuthorizeClick() が機能する理由と、ButtonTestAuthClick() を機能させるために何をする必要があるかについて 100% 確信が持てません。

誰かが私の道を投げることができる助けをありがとう。

4

3 に答える 3

6

私は同様の問題を抱えていましたが、Web フォーム クライアント ページ経由ではなく、JavaScript と AJAX 呼び出しを使用していました。web.configの認証モードを「なし」のままにしていたことがわかりました。明らかに、FormsAuthentication.SetAuthCookie() メソッドを有効にするには、ここでフォーム認証をオンにする必要があります。

<authentication mode="Forms" />

この見落としを修正すると、すべてが正常に機能し始めます。:-)

于 2012-11-02T15:02:57.580 に答える
1

途中で認証を使用してWeb APIを呼び出しています。クライアント側でユーザーをajaxで認証しないのはなぜですか?

ここでの問題は、HttpClient によって Web API に要求を送信するたびに、実際にはサーバーによって処理される新しい Web 要求であることです。すべての Cookie 情報が現在のリクエストに保持されるわけではありません。このシナリオをサポートするには、Cookie を自分で処理する必要があります。

例: 応答に含まれている場合は、ButtonAuthorizeClick メソッドで Cookie ASPXAUTH を asp.net ヘッダーに設定します。Cookie ASPXAUTH を HttpRequestMessage に設定し、HttpClient で送信します。

Web API は最近、HttpServer を使用してインプロセス サーバーを作成するためのサポートを追加し、現在のプロセスの現在のメッセージ ハンドラーに直接要求を送信できます。したがって、次のようなコードを記述できます。

HttpClient c = new HttpClient(new HttpServer(GlobalConfiguration.DefaultHandler));
c.GetStringAsync("http://localhost/api/Values").Wait();

Web API アクションで設定された Cookie ヘッダーが現在の要求のパイプラインに残るように、要求をインプロセスで送信します。チェックインは RTM リリースにはないようです。夜間ビルドhttp://aspnetwebstack.codeplex.com/discussions/353867を試すことができます。

于 2012-10-12T05:58:46.827 に答える