Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当订阅期到期时,应如何进行限制?_C#_Asp.net Core Webapi_Payment_Saas - Fatal编程技术网

C# 当订阅期到期时,应如何进行限制?

C# 当订阅期到期时,应如何进行限制?,c#,asp.net-core-webapi,payment,saas,C#,Asp.net Core Webapi,Payment,Saas,在使用.Net Core 3.1开发的Rest ApiSaaS项目中 当用户的订阅到期(需要付费)时,采用哪种方式更好 我想到了两种方法,但我认为这两种方法都会有一些问题 方法1)在生成JWT期间检查订阅状态,如果订阅期已过,则不生成JWT: 如果我使用这种方法 优势:由于令牌未提供给订阅到期的用户, 他们将无法访问其他端点。 我认为这将在不做任何其他编码工作的情况下非常安全地工作 缺点:当我需要将用户重定向到付款页面时, 我将不得不为支付端点做一项特殊的工作,因为没有令牌。(例如:密码重置方法

在使用.Net Core 3.1开发的Rest ApiSaaS项目中

当用户的订阅到期(需要付费)时,采用哪种方式更好

我想到了两种方法,但我认为这两种方法都会有一些问题

方法1)在生成JWT期间检查订阅状态,如果订阅期已过,则不生成JWT:

如果我使用这种方法

优势:由于令牌未提供给订阅到期的用户, 他们将无法访问其他端点。 我认为这将在不做任何其他编码工作的情况下非常安全地工作

缺点:当我需要将用户重定向到付款页面时, 我将不得不为支付端点做一项特殊的工作,因为没有令牌。(例如:密码重置方法) 我将使用查询字符串获得它,我想我可以为这个方法创建一个特殊的标记。 但我认为可能存在安全漏洞,因为我无法用标准授权方法保护此进程

方法2)即使订阅过期,也会生成jwt,但会员资格将受到限制:

如果我使用这种方法

优点:我可以毫无问题地使用我的标准授权方法 当我需要将用户引导到支付端点或其他端点时。 我将与jwt一起使用,安全漏洞将大大减少

缺点:我需要为订阅期过期的用户确定无法在应用程序上访问的端点 我需要在中间件中编写一个工作服务,使它们无法访问。(喜欢使用许可方法) 这两者都需要额外的编码工作,每个端点都需要额外的工作

这是我的想法

或其他解决方案

我们应该如何限制其订阅过期的用户,以及我们应该如何采取行动


非常感谢您的信息共享。

我用方法2解决了上面的问题。

我想解释一下我是如何做到的,因为我认为这可能会帮助那些将来调查这个问题的人

我在方法2中说过,jwt已经生成了,但成员资格受到限制


首先,在生成令牌时,我设置声明是否有订阅

....
new Claim(JwtClaimIdentifier.HasSubscription, hasSubscription)
我在此不作详细解释。标准索赔


订阅控制

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class SubscriptionRequiredAttribute : TypeFilterAttribute
{
    public SubscriptionRequiredAttribute()
        : base(typeof(SubscriptionFilter)) { }
}
--

--

我添加了一个覆盖订阅控制的属性

比如,;在控制器或方法中使用它,在检查base上的订阅时需要覆盖该控制器或方法

使用控制器

[SubscriptionRequired]
public class FooController
{
public async Task<IActionResult> FooMethodOne(){...}

public async Task<IActionResult> FooMethodTwo(){...}

[AllowWithoutSubscription]
public async Task<IActionResult> FooMethodThree(){...}
}
[需要订阅]
公共类FooController
{
公共异步任务FooMethodOne(){…}
公共异步任务FooMethodTwo(){…}
[AllowWithOutscription]
公共异步任务FooMethodThree(){…}
}
虽然上面的FooMethodOne和FooMethodTwo需要订阅,但FooMethodThree将在没有订阅的情况下工作

同样,所有控件都称为“AllowWithSubscription”。 它也可以在方法中称为“SubscriptionRequired”

希望它能为您的业务带来好处…

JSON web令牌用于身份验证。用户的订阅是否过期将是一个授权问题,因此应单独处理。
public class SubscriptionFilter : IAuthorizationFilter
{
    private bool AllowWithoutSubscription(AuthorizationFilterContext context)
    {
        var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;

        bool allowWithoutSubscriptionForMethod = controllerActionDescriptor.MethodInfo.CustomAttributes.Any(x => x.AttributeType == typeof(AllowWithoutSubscriptionAttribute));
        if (allowWithoutSubscriptionForMethod)
            return true;

        bool allowWithoutSubscriptionForController = controllerActionDescriptor.ControllerTypeInfo.CustomAttributes.Any(x => x.AttributeType == typeof(AllowWithoutSubscriptionAttribute));
        if (allowWithoutSubscriptionForController)
            return true;

        return false;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        if (AllowWithoutSubscription(context))
            return;

        var hasSubscription = context.HttpContext.User.Claims.First(x => x.Type == JwtClaimIdentifier.HasSubscription).Value.ToLower() == "true";
        if (!hasSubscription)
            context.Result = new BadRequestObjectResult(**ErrorCode**);
    }
}
[SubscriptionRequired]
public class FooController
{
public async Task<IActionResult> FooMethodOne(){...}

public async Task<IActionResult> FooMethodTwo(){...}

[AllowWithoutSubscription]
public async Task<IActionResult> FooMethodThree(){...}
}