属性の代わりにインラインでポリシーのすべてのハンドラーを実行することは可能ですか?


8

ほとんどのAPIでは、次のように認証を行うだけです。

[Authorize(Policy = "Foo")]
public MyApi()

私はこのポリシーをNuGetから取得していますが、変更できません。

一部のAPIでは、このポリシーが常に必要なわけではありません。これは、いくつかの構成に基づいて実行時に理解する必要があります。これをインラインで実行し、セットアップされているすべてのハンドラーが実行されるようにする方法を教えてください。

何度も検索した後、を作成しIAuthorizationService、それを使用してを呼び出すことがわかりましたAuthorizeAsync。これは私が望んでいるようですが、今実行している問題は、すべてのハンドラーAuthorizationFilterContextがコンテキスト上のリソースとしてに依存していることです。これは、AuthorizationAsyncの呼び出しではなく、属性を介してAuthorizationが行われたときに自動的に行われるようです。この場合、手動で渡す必要があります。私のコードは今このようになります:

public MyApi()
{
    var allowed = await _authorizationService.AuthorizeAsync(User, null, "Foo").ConfigureAwait(false);
}

これは私のすべてのハンドラを正しく通過するようですが、がないために機能しませんAuthorizationFilterContext

1)これはそもそも正しいアプローチですか、またはこれをインラインで実行する他の方法がありますか?これをラップする独自のポリシーを作成する方法がおそらくあり、そこで構成を確認できると思いますが、単純なインラインアプローチがある場合は、それを優先します。

2)この方法が有効である場合、AuthorizationFilterContext?手動で作成してみましたが、コンテキストからより多くのデータを渡さないと、これは実際には正しくないようですが、良い例やドキュメントが見つかりません。

new AuthorizationFilterContext(new ActionContext(HttpContext, HttpContext.GetRouteData(), new ActionDescriptor()), new IFilterMetadata[] { });


これは本当に悪い方法です。まず、アクセスチェックを後で行うため、アクセスがない場合でも、すべての呼び出しがapiメソッドにヒットする可能性があります。あなた自身のためのカスタム属性を作成し、簡単にポリシー(単一または複数のいずれか)を確認したいが、この読み取るために、ユーザまたはnot.Also良いが所有しているものは何でも確認することができます。docs.microsoft.com/en-us/aspnet/をcore / security / authorization /…
curiousBoy

回答:


-2

AuthorizationFilterContext承認パイプラインの外にいるときはありません。したがって、インラインで認証を処理しないでくださいIAuthorizationService

これは私のすべてのハンドラを正しく通過するようですが、がないために機能しませんAuthorizationFilterContext

認証ハンドラを制御できるようですね。必要がない場合、ハンドラー内で短絡認証を試しましたか?

ハンドラーはDIを介してサービスを取得できるため、IOptionsまたはIHttpContextAccessorなどを介して必要なランタイム構成を配置できます。


-2

Authorize現在の属性を継承して内部でポリシーを解決する独自の属性を作成できませんか?またはさらに使用してみてくださいIAuthorizationPolicyProvider

class MyPolicyProvider : IAuthorizationPolicyProvider
{
    private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }

    public MyPolicyProvider()
    {
        BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
    }

    public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        if (policyName.Equals("Foo"))
        {
            bool myConditionToAvoidPolicy = true;
            if (myConditionToAvoidPolicy)
            {
                return Task.FromResult<AuthorizationPolicy>(null);
            }
        }

        return BackupPolicyProvider.GetPolicyAsync(policyName);
    }
}

これはテストされていませんが、ここで詳細を確認できます。


-2

チェック条件は後で発生するように見えますが、これは良い考えではありません。チェックが後で行われるため、APIメソッドは脆弱であり、まだ開いています。ただし、属性を使用することで、それを以前のレベルでキャプチャし、カスタムロジックを適用できます。結局のところ、決定するのは「はい、アクセス権がある」または「いいえ、アクセス権はありません!!」だけです。以下はテストされていませんが、うまくいくはずです:

public class CustomAuthorize : AuthorizeAttribute
{
    private readonly PermissionAction[] permissionActions;

    public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
    {
        this.permissionActions = permissionActions;
    }

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity;
        if (!currentIdentity.IsAuthenticated) {
            // no access
        }

        bool myCondition = "money" == "happiness"; 
        if(myCondition){
           // do your magic here...
        }
        else{
          // another magic...
       }           
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.