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

时间:2018-05-30 09:19:45

标签: c# .net rest asp.net-web-api2 authorization

我有一个Web Api 2端点,我尝试使用自定义Authorize属性进行保护。在该属性内部,我检查用户是否具有必要的角色,如:

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

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

我可以在Session中存储当前访问的institutionId,如:

var session = HttpContext.Current.Session;

然而:

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

B)会话访问往往花费很长时间,因此这会在授权等场景中引入无法容忍的性能开销。

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

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

这种方法的问题是:

A)如果其他开发者使用" someInstitutionId"而不是" institutionId"作为路由参数,那么此检查将中断

B)在每次请求时传递机构ID都是一种可怕的带宽浪费

最后,我可以向用户添加一个当前加入的institutionId道具或传递cookie,但这会强制用户每次想要使用不同的机构时都要重新登录,并且他不能为不同的机构打开多个应用程序实例。一项艰难的要求。

这样的场景最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

因此,您不想使用Session,因为它违反了REST(这很棒!),但是您不希望客户端应用程序在请求内向您发送stitutionalId。这是逻辑上的问题。我的意思是考虑一下。

如果由于您不使用会话而不在请求内,那么客户端应用程序如何为您提供信息?它必须包含在每个请求中。 这不是“匪徒的可怕浪费”,您的stitutionalId不是2Go信息,所以...

只需使用JWT,将stitutionalId存储在其中,就像这样,每次客户端每次尝试访问控制器内部的方法时,Authorize属性都会检查他是否具有访问权限,即使他有多个实例,它也能很好地工作该应用程序是因为JWT将在每次请求时由JWT提供该机构ID! :)

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