【问题标题】:Read Custom request Header in OWIN Authentication在 OWIN 身份验证中读取自定义请求标头
【发布时间】:2017-06-11 17:26:34
【问题描述】:

我正在尝试使用 OWIN 为 MS Bot 框架项目提供额外/自定义身份验证,而不是使用应用 id/pwd 来自 MS 的默认身份验证。是的,Bot 实际上也是一个我标记为 Webapi 的 api。我添加了 OWIN 启动类并提供了中间件来执行 OAUTH-2 实现以验证 JWT。

由于 MS Bot 直连调用有一个默认的 Bearer 令牌作为授权标头密钥传递,因此我给了自定义提供程序以接受来自 Bot 状态的 JWT。请注意,我的机器人出现在 Web 应用程序中,该应用程序将生成一个身份验证令牌,该令牌将针对唯一用户 ID 设置为 Bot 状态,因此我需要此用户 ID 值来从 Bot 状态检索令牌。所以我能想到的最好的方法是拦截来自我的 Webchat Bot 控件的所有 ajax 调用,以添加一个自定义标头作为“x-user-id”,我将从我的 owin 中间件请求标头中读取它。

但它没有成功,因为我没有在 OWIN 中获取标头值,我在 ajax 调用中传递了该值。但是当我签入 Chrome 时,正在发送此标头。我对可能是什么问题感到困惑。

Ajax 拦截器

if (window.XMLHttpRequest && !(window.ActiveXObject)) {
        (function (send) {               
            XMLHttpRequest.prototype.send = function (data) {
                this.setRequestHeader('x-user-id', '123456789');
                send.call(this, data);
            };

        })(XMLHttpRequest.prototype.send);
    }

AppBuilder 配置

public void Configuration(IAppBuilder app)
    {
        var policy = new CorsPolicy()
        {
            AllowAnyHeader = true,
            AllowAnyMethod = true,
            AllowAnyOrigin = true,
            SupportsCredentials = true
        };
        policy.ExposedHeaders.Add("x-user-id");
        app.UseCors(new CorsOptions()
        {
            PolicyProvider = new CorsPolicyProvider
            {
                PolicyResolver = context => Task.FromResult(policy)
            }
        });
        app.Map("/api", ctx =>
        {
            ctx.UseEsoAccessTokenValidation(new EsoAccessTokenOptions
            {
                AccessTokenKey = "AccessToken",
                ChannelId = "webchat",
                Scopes = new string[] { "read", "write" }
            });

            ctx.UseWebApi(WebApiConfig.Register());
        });
    }

读取标头的代码:

private static async Task<string> GetAccessToken(OAuthRequestTokenContext context, EsoAccessTokenOptions options)
        {
            string accesstoken = string.Empty;
            var request = context.Request;
            if (request.Headers.ContainsKey("x-user-id"))
            {
                userid = request.Headers.Get("x-user-id");
            }
       }

Chrome 网络截图

请帮助我理解我在这里做错了什么?

【问题讨论】:

    标签: ajax c#-4.0 asp.net-web-api2 owin botframework


    【解决方案1】:

    需要意识到,请求总是通过相应的通道(连接器)传递,并不是您作为标头的一部分添加的所有内容都会传递给您的机器人。因此,我们只需要通过支持的机制传递这些数据。正如 Eric 提到的,一旦这种方式是利用 channelData。您作为 channelData 的一部分添加的任何内容都将通过通道并到达机器人。因此建议您尝试相同。

    示例 1:

    { "type": "conversationUpdate", "membersAdded": [], "from": { "id": "test", "name": "test" }, "serviceUrl": "https://directline.botframework.com",
    "channelData":{ "userId": "test"}
    }

    示例 2:

    { "type": "message", "text": "whats your name", "from": { "id": "user1", "name": "user1" },
    "channelData": { "userId": "test1234" }
    }`

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      我认为Direct Line 在翻译并将消息传输到您的机器人时会去除标题。但是,您可以拦截所有消息(就像您已经完成的那样)并将x-user-id 作为custom channel data 添加到每条消息中。以下是自定义渠道数据示例:https://blog.botframework.com/2017/03/28/Custom-Channel-Data#c-implementation

      【讨论】:

      • 你能告诉我如何拦截来自客户端的 ajax 调用并向正文添加一些内容吗?由于活动对象作为所有帖子调用的主体传递
      猜你喜欢
      • 2016-07-03
      • 1970-01-01
      • 2014-11-25
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      • 2013-11-28
      • 2016-03-15
      相关资源
      最近更新 更多