Asp.net web api 代码设计。如何在业务逻辑中访问api密钥?

Asp.net web api 代码设计。如何在业务逻辑中访问api密钥?,asp.net-web-api,Asp.net Web Api,这是一个代码设计问题:) 我有一个DelegatingHandler,它接受http请求头并验证API密钥。我想这是很普通的任务。在我的控制器中,我调用我的业务逻辑并传递所有与业务相关的信息。然而,现在我面临的挑战是根据特定的api键改变业务逻辑(单独的程序集)中的行为 我想到了各种可能的解决方案… 更改业务逻辑方法签名以请求api密钥 公共void SomeUseCase(entity1e1、entity2e2、字符串apiKey) 使用HttpContext.Current访问当前请求上下文

这是一个代码设计问题:)

我有一个DelegatingHandler,它接受http请求头并验证API密钥。我想这是很普通的任务。在我的控制器中,我调用我的业务逻辑并传递所有与业务相关的信息。然而,现在我面临的挑战是根据特定的api键改变业务逻辑(单独的程序集)中的行为

我想到了各种可能的解决方案…

  • 更改业务逻辑方法签名以请求api密钥

    公共void SomeUseCase(entity1e1、entity2e2、字符串apiKey)

  • 使用HttpContext.Current访问当前请求上下文。然而,我在某处读到,使用HttpContext将我的托管选项限制为IIS。有没有更合适的选择

    var request=HttpContext.Current.request;//下一步提取标题信息

  • 使用会话(真的不想走那条路……)

  • 你对这个话题有什么看法?

    尽管我不喜欢在业务逻辑方法中混入电子元素的想法,但我还是会选择1。但根据您的观点,您可能会认为api键实际上与逻辑相关


    更新#1: 我正在使用delegatingHandler来验证apiKey,一旦它被验证,我就将它添加到请求的Properties集合中

    讨论的部分是如何将“api密钥”或RegisteredIdentifier传递到业务逻辑层。现在,我正在将对象(例如IRegisteredIdentifier)作为参数传递给业务逻辑类的构造函数。我知道没有比这更优雅的方法了(?)。我考虑过更改方法签名,但我不确定这是否是接口污染。有些方法需要使用api键,而大多数不需要。经验告诉我,这个数字很可能会增加而不是减少:),所以在我的bl类中保留对它的引用似乎是一个不错的选择

    谢谢你的回答-我想所有这些都是我解决方案的一部分。我是新来的。。但就我所见,我还不能给答案打分。请放心,我仍然心存感激:)

    我会选择选项1。 但是您可以在业务逻辑中引入实体注册器标识符(Jim Arlow和Ila Neustadt的企业模式和MDA)。 api密钥可以转换为RegisteredIdentifier

    RegisteredIdentifier id = new RegisteredIdentitief(api-key);
    
    public void SomeUseCase(Entity1 e1, Entity2 e2, RegisteredIdentifier id);
    
    我会选择选项1。 但是您可以在业务逻辑中引入实体注册器标识符(Jim Arlow和Ila Neustadt的企业模式和MDA)。 api密钥可以转换为RegisteredIdentifier

    RegisteredIdentifier id = new RegisteredIdentitief(api-key);
    
    public void SomeUseCase(Entity1 e1, Entity2 e2, RegisteredIdentifier id);
    

    我建议两种不同的选择

    • 将该值提升到自定义HTTP头中(例如,类似mycompany api key:XXXX的内容)。这使您的委托处理程序更像一个标准的HTTP中介。如果您将请求转交给某个辅助内部服务器,这将非常方便

    • 将api密钥放入request.Properties字典。属性字典的思想是提供一个放置有关请求的自定义元信息的位置


    HTTP努力确保身份验证/授权与实际请求是正交的,这就是为什么我会尝试将其排除在操作签名之外。

    我建议两种不同的选择

    • 将该值提升到自定义HTTP头中(例如,类似mycompany api key:XXXX的内容)。这使您的委托处理程序更像一个标准的HTTP中介。如果您将请求转交给某个辅助内部服务器,这将非常方便

    • 将api密钥放入request.Properties字典。属性字典的思想是提供一个放置有关请求的自定义元信息的位置


    HTTP努力确保身份验证/授权与实际请求是正交的,这就是为什么我会尝试将其排除在操作签名之外。

    业务逻辑层依赖于API密钥。因此,我建议:

    interface IApiKeyProvider
    {
        string ApiGet { get; }
    }
    
    ..然后让您的BLL要求将实现该接口的对象提供给它(在构造函数、设置中,甚至在每个需要它的方法中)

    因为将来它可能不是一个API密钥。关键的一点是,这标识了BLL依赖于某个东西,并定义了某个东西的契约

    现实世界的例子:

    然后,在您的DI容器(Ninject等)中,将您自己的ConfigFileApikeProvider(或其他)实现绑定到该接口,在具有API密钥的“位置”(层)中。因此,调用BLL的应用程序指定/配置如何指定API密钥

    编辑:我误解了这是一个“如何通过HTTP实现”的问题,而不是一个代码架构/代码设计问题。因此:

    • HTTP头是传输方面的发展方向

    业务逻辑层依赖于API密钥。因此,我建议:

    interface IApiKeyProvider
    {
        string ApiGet { get; }
    }
    
    ..然后让您的BLL要求将实现该接口的对象提供给它(在构造函数、设置中,甚至在每个需要它的方法中)

    因为将来它可能不是一个API密钥。关键的一点是,这标识了BLL依赖于某个东西,并定义了某个东西的契约

    现实世界的例子:

    然后,在您的DI容器(Ninject等)中,将您自己的ConfigFileApikeProvider(或其他)实现绑定到该接口,在具有API密钥的“位置”(层)中。因此,调用BLL的应用程序指定/配置如何指定API密钥

    编辑:我误解了这是一个“如何通过HTTP实现”的问题,而不是一个代码架构/代码设计问题。因此:

    • HTTP头是一种使用HTTP的方式