私有字段值在自定义AuthorizationFilterAttribute中被覆盖

时间:2018-07-12 11:54:17

标签: c# asp.net-web-api2 custom-attributes action-filter system.web.http

Web API 2和C#7项目。

我有一个自定义授权属性AuthorizeAccessAttribute,可在控制器和端点上使用它来执行自定义授权。

我的问题是我的属性有一个私有的非静态字段accountId,我用来为其分配ID。但是,当同时处理多个请求时,该值会发生变化,就好像它是一个 static shared 变量一样。所有请求都正确设置了参数的值,但是设置后,其他所有请求的值都会更改。因此,他们正在互相争斗以设置正确值。

给我的印象是,每个请求都会初始化一个全新的上下文,控制器,属性等-这些作品,因此我不太了解发生了什么。这是预期的行为,还是我做错了什么或明显缺少什么?我希望有一些专家可以在这里为我提供帮助!

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class AuthorizeAccessAttribute : AuthorizationFilterAttribute, IAuthorizationFilter
{
    // The value of this field equals the value that was set by the latest request, when multiple requests are processed simultaneously.
    private string accountId;

    public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        // Get the value of the parameter.
        TryGetRouteParameterValue(actionContext, "parameterName", out this.accountId);

        // Make sure user is authorized.
        if (!IsAuthorized(actionContext, cancellationToken))
            HandleUnauthorizedRequest(actionContext);
    }

    private void TryGetRouteParameterValue<T>(HttpActionContext actionContext, string parameterName, out T parameterValue)
    {
        // Extract value from ActionContext arguments.
        parameterValue = (T)(actionContext?.Request?.GetRouteData()?.Values[parameterName]);
    }

    protected bool IsAuthorized(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        // When using this.accountId to perform authorization here, the value equals the value that was set by the latest request, when multiple requests are processed simultaneously.
        var sharedValue = this.accountId;

        // Auth logic here..
    }

    protected void HandleUnauthorizedRequest(HttpActionContext actionContext) { /* Handle unauthorized. */ }
}

[AuthorizeAccess]
public class SomeController : BaseApiController
{
    [AuthorizeAccess]
    public async Task<IHttpActionResult> SomeEndpoint(string parameterName)
    { .. }
}

0 个答案:

没有答案