Search code examples
azurebotframeworkazure-functionsazure-bot-service

Using OAuthCard to call Azure Function


I have a V3 Bot, and from a Dialog I want to call an Azure Function which is locked down by Azure AD V1. I want to get a token from Azure AD and use this token to access the Azure Function.

I'm trying to use OAuthCard with an Azure AD provider, and setting the Resource URL to my Azure Function https://my-function-app.azurewebsites.net

When I sign in to the OAuthCard I get the error "The application named https://my-function-app.azurewebsites.net was not found in the tenant named 880fb54d-f717-4364-9a22-df9ac5c77f6d"

The Function App does live in that tenant. Below are the OAuth Connection Settings configured in the Bot Channel Registration.

Is it possible to use OAuthCard to call an Azure Function locked down by Azure AD?

OAuth Connection String


Solution

  • I have a V3 Bot, and from a Dialog I want to call an Azure Function which is locked down by Azure AD V1. I want to get a token from Azure AD and use this token to access the Azure Function.

    If possible, you can directly make request to acquire an access token for the https://my-function-app.azurewebsites.net from you bot application, like below:

    //Acquire token
    
    var client = new RestClient($"https://login.microsoftonline.com/{tenantId}/oauth2/token");
    var request = new RestRequest(Method.POST);
    request.AddHeader("content-type", "application/x-www-form-urlencoded");
    request.AddParameter("application/x-www-form-urlencoded", $"grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}&resource={resource}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    
    var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(response.Content);
    
    var access_token = tokenResponse.access_token;
    

    TokenResponse class:

    public class TokenResponse
    {
        public string token_type { get; set; }
        public string expires_in { get; set; }
        public string ext_expires_in { get; set; }
        public string expires_on { get; set; }
        public string not_before { get; set; }
        public string resource { get; set; }
        public string access_token { get; set; }
    }
    

    and then you can call/access your function app endpoint using that access token.

    //Call Azure function using access token
    
    var client2 = new RestClient($"https://xxxxfunction.azurewebsites.net/api/HttpTriggerFunc?code=CR9X9VsIattzWybmvasvpjAXfQU2feRuV3jXC6p/0B2AlFgl4LwPMw==");
    var request2 = new RestRequest(Method.POST);
    request2.AddHeader("Authorization", $"Bearer {access_token}");
    request2.AddHeader("Content-Type", "application/json");
    
    request2.RequestFormat = DataFormat.Json;
    request2.AddBody(new { name = "Fei Han" });
    
    IRestResponse response2 = client2.Execute(request2);
    
    var funcResponse = JsonConvert.DeserializeObject<string>(response2.Content);
    
    await context.PostAsync($"Response returned from Azure function: {funcResponse}.");
    

    Test result:

    enter image description here

    Note:

    For detailed information, please check "Service to service calls using client credentials".