0

I am using Botframework adaptive dialog template (c#). I already obtained a token from a HttpRequest and saved it as a conversation state property conversation.token, now I am trying to use this token to make another API call with HttpRequest. But from the official document of HttpRequest Class, it seems there is no options to add the authentication token. I tried to add the token in the Headers, but did not work, it showed 401 Unauthorized error. How should the authorization be handled in HttpRequest in adaptive dialog?

new HttpRequest()
{
    Url = "http://example.com/json",
    ResultProperty = "conversation.httpResponse",
    Method = HttpRequest.HttpMethod.GET,
    ResponseType = HttpRequest.ResponseTypes.Json,
    Headers = new Dictionary<string, AdaptiveExpressions.Properties.StringExpression>()
    {
        {"Authorization", "Bearer ${conversation.token.content.token}"},
    },
},
new SendActivity("${conversation.httpResponse}"),
Kyle Delaney
  • 11,616
  • 6
  • 39
  • 66
Kangmin
  • 33
  • 5
  • Have you verified that the specific request with that specific token works in a more controlled environment like Postman? – Kyle Delaney Aug 07 '20 at 17:24
  • Yes, I have test it with Postman, the token works well on Postman. I also tried to hard code the token which I got from Postman POST request, but still got 401 Unauthorized error. – Kangmin Aug 07 '20 at 18:21
  • Can you provide any example API's for us to reproduce the problem with? – Kyle Delaney Aug 07 '20 at 19:38
  • Thank you for following up Kyle. I am working with insurance data so I cannot expose the API. I found a way around using HttpClient. In a CodeAction block, I did a POST request to get the token and then a GET request to call the API with the token. With HttpClient, I added the authorization: `using var client = new HttpClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);`. – Kangmin Aug 07 '20 at 21:25
  • I was asking for an example API. That means if the code you're actually using is proprietary then you would have to come up with another API that you can reproduce the problem with. Anyway, are you saying your issue is resolved? Do you want to post that as an answer? – Kyle Delaney Aug 07 '20 at 21:52
  • Yeah, I got you. But I could not find an example API that needs similar settings, otherwise I would have use that in the question description. Yes, I think I got the answer. I will post it later. Thanks! – Kangmin Aug 08 '20 at 14:27

1 Answers1

1

Instead of using HttpRequest, I made the API call inside CodeAction with custom code. First make a POST request to get the token, then make a GET request to call the main API. In the GET request, the authorization can be added in this way: client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);.

new CodeAction(async (dc, options) =>
{
    var my_jsondata = new
    {
        Username = "username",
        Password = "password"
    };
    var json = JsonConvert.SerializeObject(my_jsondata);
    var data = new StringContent(json, Encoding.UTF8, "application/json");
    var Tokenurl = "https://example.com/token?HTTP/1.1";
    using var Tokenclient = new HttpClient();
    var Tokenresponse = await Tokenclient.PostAsync(Tokenurl, data);
    string Toeknresult = Tokenresponse.Content.ReadAsStringAsync().Result;
    var Tokenjo = JObject.Parse(Tokenresult);
                                
    using var client = new HttpClient();
    var url = "https://example.com/mainapi?HTTP/1.1";
    var accessToken = Tokenjo["token"];
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
    var response = await client.GetAsync(url);
    string result = response.Content.ReadAsStringAsync().Result;
                               
    dc.State.SetValue("conversation.httpresponse", response);
    dc.State.SetValue("conversation.result", result);

    return await dc.EndDialogAsync();
}),
Kangmin
  • 33
  • 5