web-dev-qa-db-ja.com

WEB API-コントローラーまたはアクションレベルで認証(認証なし)

認証のない既存のAPIがあります。これは、いくつかのクライアントが単純な要求を行うことで使用するパブリックWeb APIです。

現在、特定のメソッドへのアクセスを許可する必要があります。

これを行う方法はありますか?残りのコントローラーとそれぞれのメソッドを、このWeb APIを既に使用しているクライアントに対して「オープン」に保ちますか?

リクエストにこの「保護された」メソッドにアクセスする権限があるかどうかを確認するにはどうすればよいですか?

9
JCruz

必要なことは、呼び出し側のユーザーが属する必要のある1つ以上のロール名を受け入れるオーバーロードを使用して、オプションで保護するメソッドに[Authorize]属性を追加することです。

次に、実装する必要があるのは、呼び出し元の認証データがプリンシパルオブジェクトに確実に変換されるようにする方法です。一般に、プリンシパルの設定は自分で行うのではなく、フレームワークに代わって行わせます。

独自のインターフェイスを提供する場合は、System.Web.Http.Filters.IAuthenticationFilterインターフェイスを実装する認証フィルターを使用できます。

だからあなたが得るものはこれです:

[MyAuthentication]
[Authorize]
public SomeClass MyProtectedMethod() {
    return new SomeClass();
}

そして、MyAuthentication属性を実装します。以下に例を示します。重要なことは、着信リクエストのコンテキストを使用して、新しいプリンシパルでcontext.Principalプロパティを設定することです。

public class MyAuthentication : ActionFilterAttribute, System.Web.Http.Filters.IAuthenticationFilter {

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        // 1. Look for credentials in the request.
        HttpRequestMessage request = context.Request;
        AuthenticationHeaderValue authorization = request.Headers.Authorization;

        // 2. If there are no credentials, do nothing.
        if (authorization == null)
        {
            return;
        }

        // 3. If there are credentials but the filter does not recognize the 
        //    authentication scheme, do nothing.
        if (authorization.Scheme != "Basic")
        {
            return;
        }

        // 4. If there are credentials that the filter understands, try to validate them.
        // 5. If the credentials are bad, set the error result.
        if (String.IsNullOrEmpty(authorization.Parameter))
        {
            context.ErrorResult = new AuthenticationFailureResult("Missing credentials", request);
            return;
        }

        Tuple<string, string> userNameAndPasword = ExtractUserNameAndPassword(authorization.Parameter);
        if (userNameAndPasword == null)
        {
            context.ErrorResult = new AuthenticationFailureResult("Invalid credentials", request);
        }

        string userName = userNameAndPasword.Item1;
        string password = userNameAndPasword.Item2;

        IPrincipal principal = await AuthenticateAsync(userName, password, cancellationToken);
        if (principal == null)
        {
            context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);
        }

        // 6. If the credentials are valid, set principal.
        else
        {
            context.Principal = principal;
        }

    }


    ... other interface methods here
}

これがあなたが正しい軌道に乗るのに役立つことを願っています。詳細については、この投稿を確認してください: http://www.asp.net/web-api/overview/security/authentication-filters

19
Robba

特定のAPIメソッドとコントローラーレベルで[Authorize]属性を使用できます。コントローラーレベルで[Authorize]属性を設定した場合、認証なしでアクセスするAPIメソッドに[AllowAnonymous]属性を使用できます。

10
Rahul

デフォルトでは、承認はアプリケーションでグローバルに無効になっています。アクションフィルター[Authorize]を追加することで、コントローラーに許可されたリクエストのみを許可することができます。

[Authorize]  // This will enforce all methods inside should be authorized
public class AuthorizeController : ApiController
{
      //this method will only be called if user is authorized
      public IHttpActionResult GetList()
      {
         return Ok();
      }
}

特定の方法のみを許可することもできます。

public class AuthorizeController : ApiController
{
      [Authorize] //this method will only be called if user is authorized
      public IHttpActionResult GetList()
      {
         return Ok();
      }

      // This method can still be called even if user is not authorized
      public IHttpActionResult GetListUnauthorized()
      {
         return Ok();
      }
}

または、承認が必要なコントローラー内の一部のメソッドで承認を無効にします。

[Authorize]
public class AuthorizeController : ApiController
{
      //this method will only be called if user is authorized
      public IHttpActionResult GetList()
      {
         return Ok();
      }

      [AllowAnonymous]// This method can be called even if user is not authorized due the AllowAnonymous attribute
      public IHttpActionResult GetListUnauthorized()
      {
         return Ok();
      }
}

以下を使用して、メソッドへのアクセスを許可するユーザーを設定することもできます。

[Authorize(Users="Joey,Billy")]

または、次を使用するルールによって:

[Authorize(Roles="Administrator,Manager")]

または、この回答のように、より複雑なAuthorize属性を作成することもできます(クレームに基づく): クレームによる承認属性

5
Rafael A. M. S.

AuthenticatedではなくAuthorizedにしたくないメソッドで[AllowAnonymous]を使用して解決し、Authorizationをオーバーライドしました。

0
Ruben Lopez