18

ASP.NET Web API を使用しています。また、属性を追加して、次のように API コントローラーへのアクセス レベルを指定する機能も気に入っています。

[Authorize]
public IEnumerable<Activity> Get()

ここまでは良いのですが、ロールを使用するとコンセプトが崩れてしまいます。

[Authorize(Roles = "Manager")]
public IEnumerable<Activity> Get()

ユーザーがしばらく前にシステムにログオンした後、ある時点で「禁止」されているリソースにアクセスした可能性があります。ユーザーが再度ログオンしようとしても意味がありません。彼らの正当なアカウントにはその URL へのアクセス権がないためです。しかし現在、間違ったアカウントでログオンしたかのように、403 (禁止) ではなく 401 (無許可) が返されます。ただし、ユーザーは 1 つのアカウントしか持っておらず、ユーザーが他の誰かに属するアカウントを要求することは意図されていません。

他の誰かがこの問題に対処しましたか? これを修正する方法を知っている人はいますか?これを修正するコードを書きたいと思っていますが、現在、どこから始めればよいか途方に暮れています。

4

3 に答える 3

35

Parv の提案を読んで、[WebApiAuthorize]という次のカスタム フィルターを作成しました。

重要なのは、HandleUnauthorizedRequest() メソッドです。コードがこのメソッド内で実行されている場合、それはユーザーが「何らかの理由で」許可されていないためです....だから今、「理由」を判断するだけです....そして、次のいずれかを行います。

  1. デフォルトの動作の基本メソッドを呼び出します (401 を返す)... または ....
  2. 403 で独自の応答を返します。

ご覧のとおり、適切な場合 (認証されているが、許可されていない場合) は 403 を返します。

public class WebApiAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext ctx)
    {
        if (!ctx.RequestContext.Principal.Identity.IsAuthenticated)
            base.HandleUnauthorizedRequest(ctx);
        else
        {
            // Authenticated, but not AUTHORIZED.  Return 403 instead!
            ctx.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
        }
    }
}

使用するには、このようなコントローラーまたはアクションにカスタム フィルターをスローするだけです.....

[WebApiAuthorize(Roles = "YourRoleA,YourRoleB")]
public class AdminController : ApiController
{
    public List<Admin> GetAdmins()
    {
        ...
    }
} 
于 2015-05-08T19:19:19.843 に答える