1

MVC C# WebAPI を使用したい。

誰がリクエストを送信しているかをサーバー レベルで知る最善の方法は何ですか。たとえば、ログイン リクエストを受信して​​認証した場合、WebAPI はカスタム トークンを返す必要がありますか? これは、サーバーがさらなる呼び出しを識別するためにどこかに保存する必要がありますか?

もしそうなら、トークンは WebAPI がすでに埋め込んでいるものですか、それとも私が書く必要があるものですか?

そのトークンをサーバーに保存するための推奨される方法は何ですか? 理想的には、セッションを使用したくありません。

また、ここでは述べませんが、多くの理由から、私はメンバーシップの使用があまり好きではありません。

ありがとうございます。

4

2 に答える 2

1

認証を行う最善の方法は、組み込みシステムを使用することですが、それらが気に入らないとすでに述べているので、最善の方法ではないことに同意する必要があります。

メンバーシップを使用するかどうかに関係なく、認証は MVC や WebForms と同じように WebApi で機能します。リクエストが入ったときにフレームワークによって自動的に認証される FormsAuthentication Cookie を使用します。これは HttpContext.Current.User.Identity オブジェクトに格納されます。

これは、少なくとも .NET 2.0 以降、暗号化技術の改善以外には (あまり) 変更されていません。

于 2013-09-25T02:19:28.713 に答える
1

トークン認証で説明していることを正確に実行するオープンソースのMVC4 WebAPI アプリケーションを作成しました。ここで見つけることができますWebAPISoup .

これはasp.net メンバーシップ プロバイダーではありません。カスタムのDelegatingHandlerを使用すると、リクエスト ヘッダーで有効なアプリ IDトークンの値を検査し、データベース (最初に EF5 コード) に対して検証してから、リクエストの続行を許可するだけです。

mapHttpRouteでハンドラーを設定することにより、これをグローバルに処理するようにアプリケーションを構成します。

WebApiConfig.cs

 config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: null,
            handler: HttpClientFactory.CreatePipeline(
                      new HttpControllerDispatcher(config),
                      new DelegatingHandler[] { new Pipeline.AuthMessageHandler() })

        );

AuthMessageHandler

public class AuthMessageHandler : DelegatingHandler
{

    private const string AppIdHeader = "AppId";
    private const string AppTokenHeader = "AppToken";
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        IEnumerable<string> appIdValues;
        IEnumerable<string> appTokenValues;
        HttpStatusCode responseCode = HttpStatusCode.OK;
        Guid AppIdGuid;
        var DoesHaveAppId = request.Headers.TryGetValues(AppIdHeader, out appIdValues);
        var DoesHaveAppToken = request.Headers.TryGetValues(AppTokenHeader, out appTokenValues);
        //Forces Json to be request Body type
        request.Headers.Accept.Clear();
        request.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json");
        IPrincipal principal = null;
        if (DoesHaveAppId && DoesHaveAppToken)
        {
            if (Guid.TryParse(appIdValues.FirstOrDefault(), out AppIdGuid))
            {
                principal = ValidateAuthentication(AppIdGuid, appTokenValues.FirstOrDefault());
                if (principal != null) //Valid User
                {
                    System.Threading.Thread.CurrentPrincipal = principal;
                    if (IsAppOverLimit(AppIdGuid))
                    {
                        responseCode = (HttpStatusCode)429;
                    }
                }
                else//User failed to authenticate
                    responseCode = HttpStatusCode.Unauthorized;
            }
        }
        else//User didn't supply Key/Token
            responseCode = HttpStatusCode.Forbidden;


        return base.SendAsync(request, cancellationToken)
            .ContinueWith(task =>
            {
                var response = task.Result;
                if (responseCode == HttpStatusCode.OK)
                    return response;
                else
                    return request.CreateResponse(responseCode);
            });
    }
}

トークン認証リクエストを処理するために作成した AuthMessageHandler は、こちらにあります

于 2013-10-03T12:54:16.693 に答える