【问题标题】:Authorization for Microsoft App ID xxx failed with status code Forbidden and reason phrase 'Forbidden'Microsoft App ID xxx 的授权失败,状态代码为 Forbidden 和原因短语“Forbidden”
【发布时间】:2017-03-24 04:19:33
【问题描述】:

我的机器人在以下代码行中不断失败,并在 Skype、WebChat 和 FB 聊天中出现错误。我尝试通过应用设置和 web.config 输入 MS 应用 ID 和密码。这在模拟器中运行良好,没有任何错误。当我运行远程调试时,我发现这行代码在 Webchat、Skype 和 FB messenger 上失败了:

await connector.Conversations.ReplyToActivityAsync(reply1);

我的机器人与 SmartThings 集成,因此智能配件按预期打开和关闭,但应在聊天中返回的响应似乎失败。我尝试创建一个新的机器人服务应用程序,但它也失败了。

更新包括所有代码:

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Connector;
using System.Net.Http.Headers;
using System.Threading;
using Microsoft.IdentityModel.Protocols;
using System.Configuration;

namespace FirstBotApp
{
[BotAuthentication]

public class Switches
{
    public string name { get; set; }
    public string value { get; set; }

}



public class MessagesController : ApiController
{

    static HttpClient client = new HttpClient();
    static HttpResponseMessage responsemain = null;
    static int j = 0;

    static void ShowSwitches(Switches[] switches)
    {

        for (int i = switches.Length - 1; i >= 0; i--)
        {
            Console.WriteLine($"Name: {switches[i].name}\tPrice: {switches[i].value}\t");
        }
        return;
    }

    static async Task<Switches[]> GetSwitchesAsync(string path)
    {
        Switches[] switches = null;
        responsemain = await client.GetAsync(path);
        //Console.WriteLine(client.GetAsync(path));
        //Console.WriteLine(response);
        if (responsemain.IsSuccessStatusCode)
        {
            //Console.WriteLine($"Successful response: {response.StatusCode}");
            var response1 = await client.GetStringAsync("");
            Console.WriteLine($"{response1}");

            switches = await responsemain.Content.ReadAsAsync<Switches[]>();

            //JObject j = JObject.Parse(response1);
        }
        else Console.WriteLine($"Error in response: {responsemain.StatusCode}");

        return switches;
    }

    static async Task<Switches> UpdateSwitchesAsync(Switches switches)
    {
        Console.WriteLine("Turning off the light");
        HttpResponseMessage response = await client.PutAsJsonAsync($"switches/off?room=LivingRoom", switches);
        response.EnsureSuccessStatusCode();
        Console.WriteLine($"The response from the server was: {response.StatusCode}");

        // Deserialize the updated switches from the response body.
        switches = await response.Content.ReadAsAsync<Switches>();
        Thread.Sleep(10000);
        Console.WriteLine($"Turning on the light");

        response = await client.PutAsJsonAsync($"switches/on?room=LivingRoom", switches);
        Console.WriteLine($"The response from the server was: {response.StatusCode}");
        Thread.Sleep(10000);
        return switches;
    }

    static async Task<HttpStatusCode> DeleteSwitchesAsync(string id)
    {
        HttpResponseMessage response = await client.DeleteAsync($"api/switchess/{id}");
        return response.StatusCode;
    }


    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {

        Switches[] switches = null;
        ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        //string appdId = AppSettings.Settings["MicrosoftAppId"];
        //string appPassword = ConfigurationManager.AppSettings["MicrosoftAppPassword"];
        if (j == 0)
        {
            //client.Timeout = TimeSpan.FromSeconds(4);

            //Declaration of client and Switches variable

            string accessToken = "xxxxx";
            client.BaseAddress = new Uri("xxxxx");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
            j++;
            //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Authorization", "Bearer " + accessToken);
        }

        if (activity.Type == ActivityTypes.Message)
        {
            //, appdId, appPassword);
            //Switches switches = new Switches;
            Activity reply1;// = activity.CreateReply($"breakpoint1");
                            //await connector.Conversations.ReplyToActivityAsync(reply1);


            switch (activity.Text.ToLower())
            {
                case"turn on livingroom":
                    try
                    {
                        Console.WriteLine("Turning on the light");
                        responsemain = await client.PutAsJsonAsync($"switches/on?room=LivingRoom", switches);
                        responsemain.EnsureSuccessStatusCode();
                        //Console.WriteLine($"The response from the server was: {responsemain.StatusCode}");

                        // Deserialize the updated product from the response body.
                        switches = await responsemain.Content.ReadAsAsync<Switches[]>();
                        reply1 = activity.CreateReply($"Successfully turned on LivingRoom Light");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }
                    catch
                    {
                        reply1 = activity.CreateReply($"Error");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }
                    break;


                case "turn off livingroom":
                    try
                    {
                        Console.WriteLine("Turning off the light");
                        responsemain = await client.PutAsJsonAsync($"switches/off?room=LivingRoom", switches);
                        responsemain.EnsureSuccessStatusCode();
                        Console.WriteLine($"The response from the server was: {responsemain.StatusCode}");

                        // Deserialize the updated product from the response body.
                        switches = await responsemain.Content.ReadAsAsync<Switches[]>();
                        reply1 = activity.CreateReply($"Successfully turned off LivingRoom Light");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }

                    catch
                    {
                        reply1 = activity.CreateReply($"Error");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }
                    break;


                default: //"What lights are on?":
                    try
                    {
                        switches = await GetSwitchesAsync("");
                        //Console.WriteLine($"About to show the product");
                        ShowSwitches(switches);
                        //await connector.Conversations.ReplyToActivityAsync(switches[].ToString);

                        for (int i = switches.Length - 1; i >= 0; i--)
                        {
                            reply1 = activity.CreateReply($"Room: ");//{switches[i].name}\tStatus: {switches[i].value}\t");
                            responsemain.EnsureSuccessStatusCode();

                            await connector.Conversations.ReplyToActivityAsync(reply1);
                        }



                        break;
                    }
                    catch
                    {

                    }
                    break;




            }

            // calculate something for us to return
            //int length = (activity.Text ?? string.Empty).Length;

            // return our reply to the user
            //Activity reply = activity.CreateReply($"You sent {activity.Text} which was {length} characters");
            //await connector.Conversations.ReplyToActivityAsync(reply);
        }
        else
        {
            HandleSystemMessage(activity);
        }
        // var response = Request.CreateResponse(HttpStatusCode.OK);

        return responsemain;
    }

    static Activity HandleSystemMessage(Activity message)
    {
        if (message.Type == ActivityTypes.DeleteUserData)
        {
            // Implement user deletion here
            // If we handle user deletion, return a real message
        }
        else if (message.Type == ActivityTypes.ConversationUpdate)
        {
            // Handle conversation state changes, like members being added and removed
            // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
            // Not available in all channels
        }
        else if (message.Type == ActivityTypes.ContactRelationUpdate)
        {
            // Handle add/remove from contact lists
            // Activity.From + Activity.Action represent what happened
        }
        else if (message.Type == ActivityTypes.Typing)
        {
            // Handle knowing tha the user is typing
        }
        else if (message.Type == ActivityTypes.Ping)
        {
        }

        return null;
    }``
    //client.dispose();

}
}

【问题讨论】:

  • 我投票决定将此问题作为离题结束,因为它必须包含要重现的详细信息。检查stackoverflow.com/questions/42611413/… 的内容是否对您有帮助。
  • @MrBrooks 您能否添加更多代码,尤其是“reply1”的来源或生成方式?
  • @JustShadow 用我的完整代码更新了帖子
  • 模拟器在身份验证方面的工作方式略有不同;例如,如果您没有设置您的 ID 和密码,它会忽略身份验证。 ConnectorClient 构造函数有一个替代定义,可让您在调用它时指定凭据,但如果您的 web.config 设置正确,则不需要它。

标签: c# botframework azure-bot-service


【解决方案1】:

在使用远程调试进行了一些额外的故障排除后,我发现了该错误。根据@JimLewallen 的回复,我仔细查看了连接器对象的“凭据”部分。 Botframework 3.0 版的 OAuthScope(远程调试器本地的连接器-> 凭据->OAuthScope)指向 api.botframework.com/.default,而它本应指向“graph.microsoft.com /。默认”。当我使用机器人模板在 Visual Studios 中创建新的机器人服务应用程序时,OAuthScope 显示了正确的端点。

不正确的值: OAuthScope "api.botframework.com/.default"

正确值:Image from the Remote Debugger showing the correct OAuthScope

【讨论】:

    猜你喜欢
    • 2017-06-15
    • 2015-11-28
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    相关资源
    最近更新 更多