【问题标题】:How to allow multiple roles to access route through RouteClaimsRequirement如何通过RouteClaimsRequirement允许多个角色访问路由
【发布时间】:2021-04-15 08:33:23
【问题描述】:

在常规类型的场景中,如果路由可用,例如仅对“高级”用户说,ocelot.global.json 将有 RouteClaimsRequirement,如下所示:

"RouteClaimsRequirement" : { "Role" : "Premium" }

这会被翻译成KeyValuePair<string, string>(),而且效果很好。 但是,如果我要为 2 类用户打开一条路线,例如。 “Regular”和“Premium”,我究竟如何才能做到这一点?

【问题讨论】:

标签: ocelot


【解决方案1】:

我找到了一种覆盖默认 Ocelot 中间件的方法。下面是一些有用的sn-ps代码:

首先,在Startup.cs的Configuration()中覆盖默认的AuthorizationMiddleware:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        var config = new OcelotPipelineConfiguration
        {
            AuthorisationMiddleware 
                = async (downStreamContext, next) =>
                await OcelotJwtMiddleware.CreateAuthorizationFilter(downStreamContext, next)
        };
        
        app.UseOcelot(config).Wait();
    }

如您所见,我正在使用自定义的 OcelotJwtMiddleware 类。这是粘贴的那个类:

public static class OcelotJwtMiddleware
{
    private static readonly string RoleSeparator = ",";
    
    public static Func<DownstreamContext, Func<Task>, Task> CreateAuthorizationFilter 
        => async (downStreamContext, next) =>
        {
            HttpContext httpContext = downStreamContext.HttpContext;
            var token = httpContext.Request.Cookies[JwtManager.AuthorizationTokenKey];
            if (token != null && AuthorizeIfValidToken(downStreamContext, token))
            {
                await next.Invoke();
            }
            else
            {
                downStreamContext.DownstreamResponse =
                    new DownstreamResponse(new HttpResponseMessage(HttpStatusCode.Unauthorized));
            }
        };
    
    private static bool AuthorizeIfValidToken(DownstreamContext downStreamContext, string jwtToken)
    {
        IIdentityProvider decodedObject = new JwtManager().Decode<UserToken>(jwtToken);
        if (decodedObject != null)
        {
            return downStreamContext.DownstreamReRoute.RouteClaimsRequirement["Role"]
                ?.Split(RoleSeparator)
                .FirstOrDefault(role => role.Trim() == decodedObject.GetRole()) != default;
        }

        return false;
    }
}

这里的JwtManager 类只是我使用默认Jwt NuGet 包制作的小工具,没什么特别的。此外,JWT 被存储为 Cookie,虽然不安全,但在这里无关紧要。如果您碰巧复制粘贴您的代码,您将遇到与此相关的小错误,但只需使用您自己的身份验证令牌实现将其切换出来。 实现这2个sn-ps后,ocelot.global.json就可以有RouteClaimsRequirement这样的:

"RouteClaimsRequirement" : { "Role" : "Premium, Regular" }

这将识别在其 Cookie 中使用常规的客户端以及使用高级版的客户端。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2013-12-30
    相关资源
    最近更新 更多