代码之家  ›  专栏  ›  技术社区  ›  qubits

WebApi 2-多个同时上下文中的授权,REST状态管理

  •  1
  • qubits  · 技术社区  · 6 年前

    我有一个Web Api 2端点,我正试图通过自定义授权属性来保护它。在该属性中,我检查用户是否具有以下必要的角色:

                if (!user.HasRoleInInstitution(institutionId, Role.SomeRole))
                {
                    filterContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
                    return;
                }
    

    我遇到的问题是机构ID。端点应该可以在机构上下文中访问,其中每个用户可以在不同的机构中拥有不同的角色,因此检查应该检查用户是否在用户正在访问的给定机构中拥有角色。

    我可以在会话中存储当前访问的institutionId,如下所示:

    var session = HttpContext.Current.Session;
    

    然而,这是:

    A) 这违反了REST原则,因为端点应该是无状态的

    B) 会话访问往往需要很长时间,因此这会带来在授权等场景中无法忍受的性能开销。

    我还可以在每次请求时从客户端传递institutionId,然后使用RouteData在属性中检索它,如:

    var institutionId = filterContext.ControllerContext.RouteData["institutionId"]; 
    

    这种方法的问题是:

    A) 如果另一个开发人员使用“someInstitutionId”而不是“institutionId”作为路由参数,那么该检查将中断

    B) 每次请求都传递institutionId是对带宽的可怕浪费

    最后,我可以向用户添加一个当前已访问的institutionId道具或传递cookies,但这会迫使用户在每次想使用不同机构时重新登录,并且他不能为不同机构打开多个应用程序实例,这是一个硬要求。

    对于这种情况,最好的方法是什么?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Max    6 年前

    所以你不想使用Session,因为它不利于REST(这太好了!)但你不希望客户端应用程序在请求中向你发送institutionId。。。这是一个逻辑问题。我是说好好想想。

    如果由于您不使用会话而不在请求中,客户端应用程序如何向您提供信息?它必须包含在每个请求中。 这并不是“对bandwitch的可怕浪费”,你的机构ID不是2Go信息,所以。。。

    只需使用JWT,将institutionId存储在内部,就像每次客户端尝试访问控制器中的方法时一样,“授权”属性将检查他是否获得了访问权限,即使他有多个应用程序实例,它也会非常有效,因为每次请求时,JWT都会提供institutionId:)

    如果您不希望用户每次在另一个机构中打开应用程序时都登录,只需让客户端应用程序在令牌中写入institutionId即可。所以他使用ClientApp 1登录,你给他一个没有institutionId的令牌,但当ClientApp 1打电话时,它会在令牌中写下institutionId,这样,您可以检查访问权限,如果客户端打开ClientApp 2,您将自动提供您提供给ClientApp 1的令牌(因此没有institutionId的令牌),ClientApp 2将覆盖institutionId并向您发送与ClientApp 2相关的institutionId。