Microsoft Bot Framework多租户凭证C#

时间:2017-11-09 16:19:49

标签: c# frameworks bots multi-tenant credentials

背景

我在C#中创建了一个工作机器人,但我没有将它扩展为多租户机器人。我在Microsoft门户using this technique中创建了多个机器人,以便从消息传递端点识别自己:

我可以在MessagesController中从URL中获取LastSegment并将其存储在PrivateConversationData中,这样我就知道哪个机器人在当前对话中正在讲话。我打算使用这个存储的'bot id'来检索Microsoft AppId&来自web.config的密码(机器人的凭据存储为一系列自定义条目,而不是标准的appSettings,因为它只适用于单个机器人。)

凭据问题

身份验证(几乎)作为described here运行良好,除非在.ConfigureAwait(false)中使用异步代码时我无法获取HttpContext.Current,因为它在另一个线程上运行时变为null。这意味着我无法通过在web.config中查找它们或通过调用GetCredentialsFromClaims()来获取经过身份验证的用户的凭据,因为我已经丢失了经过身份验证的用户。如果我使用.ConfigureAwait(true)我只会在整个地方遇到死锁。

我在web.config中有凭据,但它们是按机器人存储的,我需要上面URL中的'bot id'才能获得凭据。

问题

问题的症结在于:我需要URL来获取'bot id',我需要'bot id'来从web.config获取凭据,但是我永远无法可靠地访问URL在代码中传递了.ConfigureAwait(false)。另一方面,我无法从PrivateConversationData获取'bot id',因为我需要机器人的凭据才能加载它。有点鸡肉和鸡蛋: - (

如果有人对我可能做错了什么有任何想法,或者有另一种方法知道哪个'bot id'正在执行,我会非常感激。

由于

1 个答案:

答案 0 :(得分:0)

请在下面给出示例代码。

public class StartUp {

    public void Configuration(IAppBuilder app) {
        var builder = new ContainerBuilder();

        //Note: Initialize / register the Metadata Service that can bring the tenant details from the corresponding store
        builder.RegisterType<TenantMetadataService>().As<ITenantMetadataService>();

        //Note: This helps you in accessing the TenantMetadata from any constructor going forward after the below registry
        builder.Register(ti => TenantMetadata.GetTenantMetadataFromRequest()).InstancePerRequest();

        //TODO: Register the various services / controllers etc which may require the tenant details here
    }

}

public class TenantMetadata {

    public Guid TenantId { get;set; }
    public Uri TenantUrl { get;set; }
    public string TenantName { get;set; }

    public static TenantMetadata GetTenantMetadataFromRequest() {

        var context = HttpContext.Current;

        //TODO: If you have any header like TenantId coming from the request, you can read and use it
        var tenantIdFromRequestHeader = "";

        //TODO: There will be a lazy cache that keeps building the data as new tenant's login or use the application
        if(TenantCache.Contains(...))return TenantCache[Key];

        //TODO: Do a look-up from the above step and then construct the metadata
        var tenantMetadata = metadataSvc.GetTenantMetadata(...);
        //TODO: If the data match does not happen from the Step2, build the cache and then return the value.
        TenantCache.Add(key,tenantMetadata);
        return tenantMetadata;
    }
}

注意 上面的代码片段使用各种服务占位符,缓存和其他需要根据设计的应用程序服务使用的方法。如果您不希望缓存租户元数据,如果它可能包含一些敏感数据,则可以删除缓存实现部分。

此实现可以分布在您的所有面向Web的门户网站上,例如Web UI,Web Api和WebJobs等,以便它在所有应用程序中都相同,并且易于测试和使用。

HTH。