如何重新验证多租户 ASP.NET 身份的令牌?

How to re-validate token for multi-tenant ASP.NET Identity?

我已经实施了自定义 OAuthAuthorizationServerProvider 来为帐户登录添加域限制。一切都很好。但是,我遇到了一个问题,一旦用户获得令牌,他们就可以将其用于他们想要的任何系统。例如:

他们使用正确的用户名和密码请求 TokenEndpointPath(假设它是租户 1 的管理员帐户):http://localhost:40721/api/v1/account/auth 并接收 Bearer Token。

现在他们用它来访问:http://localhost:40720/api/v1/info/admin,属于租户 0。该请求被视为已授权。

我尝试更改 CreateProperties 方法但没有帮助:

    public static AuthenticationProperties CreateProperties(string userName)
    {
        var tenant = DependencyUtils.Resolve<IdentityTenant>();
        IDictionary<string, string> data = new Dictionary<string, string>
        {
            { "userName", userName },
            { "tenantId", tenant.Tenant.Id.ToString() },
        };
        return new AuthenticationProperties(data);
    }

我也尝试覆盖 ValidateAuthorizeRequest,但在我的调试中从未调用它。

我是否需要在其他任何地方实施检查,以便令牌仅对 domain/correct 个租户有效?

(注意:一个租户可能有多个域,所以如果我可以针对正确的租户手动执行帐户检查而不是坚持一个域,那就太好了。但是,如果我能做到这一点,那就太好了,否则,只需将令牌限制在域中即可)

不是我问题的直接答案(因为它不在 ASP.NET 身份工作流程中),但我应用的最简单的修复是改用 ActionFilterAttribute

public class DomainValidationFilter : ActionFilterAttribute
{

    public override Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        // Other Code...

        // Validate if the logged in user is from correct tenant
        var principal = actionContext.ControllerContext.RequestContext.Principal;
        if (principal != null && principal.Identity != null && principal.Identity.IsAuthenticated)
        {
            var userId = int.Parse(principal.Identity.GetUserId());
            // Validate against the tenant Id of your own storage, and use this code to invalidate the request if it is trying to exploit:
           actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Unauthorized, "Invalid Token"); 

        }

        return base.OnActionExecutingAsync(actionContext, cancellationToken);
    }

}

然后通过在 FilterConfigWebApiConfig 中注册它来将过滤器应用于所有操作:

config.Filters.Add(new DomainValidationFilter());