我正在尝试使用OWIN为MS Bot-framework项目提供额外/自定义身份验证,而不是使用app id / pwd从MS进行默认身份验证。是的,Bot实际上也是一个api我标记的Webapi。我添加了OWIN启动类并提供了中间件来执行OAUTH-2实现来验证JWT。
由于MS Bot直接线路调用将默认承载令牌作为授权标头密钥传递,我给定了自定义提供程序以接受来自Bot状态的JWT。请注意我的机器人出现在一个Web应用程序中,该应用程序将生成一个身份验证令牌,该令牌将在Bot状态下针对唯一用户ID进行设置,因此我需要此用户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");
}
}
请帮助我理解我在这里做错了什么?
答案 0 :(得分:1)
需要意识到,请求总是通过相应的通道(连接器)而不是您作为标题的一部分添加的所有内容都将传递给您的机器人。因此,我们只需要通过支持的机制传递这些数据。正如埃里克所说,一旦这样做是利用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"
}
强>
}`
希望这有帮助。
答案 1 :(得分:0)
我认为Direct Line
会删除标题,因为它会将消息转换并传输到您的机器人。但是,您可以拦截所有邮件(就像您已经完成的那样),并将x-user-id
添加为custom channel data
到每封邮件。以下是自定义渠道数据的示例:https://blog.botframework.com/2017/03/28/Custom-Channel-Data#c-implementation