如何为多租户ASP.NET标识重新验证令牌?

时间:2016-12-17 16:23:40

标签: asp.net asp.net-web-api2 multi-tenant asp.net-identity-2

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

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

现在他们使用它来访问: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,但我的调试中从未调用它。

我是否需要在其他任何地方执行检查,因此令牌仅对域/正确的租户有效?

(注意:租户可能有多个域名,所以如果我可以手动对正确的租户执行帐户检查而不是坚持使用域名,那就太棒了。但是,如果我能做到这一点,那就更好了,或者只是限制域的令牌是好的)

1 个答案:

答案 0 :(得分:0)

不能直接回答我的问题(因为它不在ASP.NET Identity工作流程内),但我应用的最简单的修复方法是使用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());