4

AspNetWebApiを使用した承認を調査してきましたが、この件に関する情報は少しまばらです。

次のオプションがあります。

  1. クエリ文字列にAPIトークンを渡す
  2. APIトークンをヘッダーとして渡す
  3. 基本認証を使用してAPIトークンを渡す
  4. APIトークンをjsonのリクエストペイロードに渡します。

一般的に推奨される方法はどれですか?

また、ポイント4)についても疑問に思っていますが、AuthorizationFilterAttributeのOnAuthorizationメソッドでjsonペイロードを調べて、APIトークンが正しいかどうかを確認するにはどうすればよいですか?

4

1 に答える 1

5

承認のための本当に安全なオプションが必要な場合は、OAuthのようなものが最適です。このブログ投稿では、廃止されたWCF Web APIを使用したかなり徹底的なサンプルを提供していますが、コードの多くは回収可能です。または、少なくとも、このブログ投稿に示されているように、HTTP基本認証を使用してください。Aliostadが指摘しているように、トークンが安全に保たれるように、基本認証ルートを使用する場合は、HTTPSを使用していることを確認してください。

自分でロールすることにした場合(ほとんどの場合、上記のいずれかのオプションよりもはるかに安全性が低くなります)、HTTPヘッダールートを使用する場合にAuthorizationHanlderに必要なコードサンプルを以下に示します。UserPrinicipalがWebAPIクラスで処理される方法が変更される可能性が高いため、このコードは最初のプレビューリリースにのみ適していることに注意してください。次のようにAuthorizationHandlerをワイヤリングする必要があります。

    GlobalConfiguration.Configuration.MessageHandlers.Add(new AuthenticationHandler());

ヘッダートークンのコード:

public class AuthenticationHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        var requestAuthTokenList = GetRequestAuthTokens(request);
        if (ValidAuthorization(requestAuthTokenList))
        {
            //TODO: implement a Prinicipal generator that works for you
            var principalHelper = GlobalConfiguration.Configuration
                .ServiceResolver
                    .GetService(typeof(IPrincipalHelper)) as IPrincipalHelper;

            request.Properties[HttpPropertyKeys.UserPrincipalKey] = 
                principalHelper.GetPrinicipal(request);

            return base.SendAsync(request, cancellationToken);
        }
        /*
        ** This will make the whole API protected by the API token.
        ** To only protect parts of the API then mark controllers/methods
        ** with the Authorize attribute and always return this:
        **
        ** return base.SendAsync(request, cancellationToken);
        */
        return Task<HttpResponseMessage>.Factory.StartNew(
            () => new HttpResponseMessage(HttpStatusCode.Unauthorized)
                {
                    Content = new StringContent("Authorization failed")
                });
    }

    private static bool ValidAuthorization(IEnumerable<string> requestAuthTokens)
    {
        //TODO: get your API from config or however makes sense for you
        var apiAuthorizationToken = "good token";
        var authorized = requestAuthTokens.Contains(apiAuthorizationToken);

        return authorized;
    }

    private static IEnumerable<string> GetRequestAuthTokens(HttpRequestMessage request)
    {
        IEnumerable<string> requestAuthTokens;
        if (!request.Headers.TryGetValues("SomeHeaderApiKey", out requestAuthTokens))
        {
            //Initialize list to contain a single not found token:
            requestAuthTokens = new[] {"No API token found"};
        }
        return requestAuthTokens;
    }
}
于 2012-05-03T15:55:59.223 に答える