Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Unable to call AAD Protected Azure Functions from ASP.Net Application #995

Open
7 tasks
snapfisher opened this issue Feb 19, 2021 · 4 comments
Open
7 tasks

Comments

@snapfisher
Copy link

Which version of Microsoft Identity Web are you using?
Note that to get help, you need to run the latest version.
1.6

Where is the issue?

  • Web app
    • Sign-in users
    • Sign-in users and call web APIs
  • Web API
    • Protected web APIs (validating tokens)
    • Protected web APIs (validating scopes)
    • [x ] Protected web APIs call downstream web APIs
  • Token cache serialization
    • In-memory caches
    • Session caches
    • Distributed caches
  • Other (please describe)

Is this a new or an existing app?

C. This is a new app
Repro

var scope = _configuration["CallApi:ScopeForAccessToken"];
var accessToken = await _tokenAcquisition.GetAccessTokenForAppAsync(scope);

var client2 = _clientFactory.CreateClient();
client2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client2.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var response = await client2.GetStringAsync(url);

Given this configuration

"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxx.onmicrosoft.com",
"TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"CallbackPath": "/.auth/login/aad/callback",
"ClientSecret": "x"
},
"CallApi": {
"ScopeForAccessToken": "http://xxxxxxx/.default",
"ApiBaseAddress": "https://as-xxxxxxx.azurewebsites.net/api/HttpsDemo?code=xxxxxx==",
"Resource": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
},

Expected behavior
This should work, and I should be able to access the API. The function app is protected with AAD. I can log into the function app in postman my signing in, so I know that works.

Actual behavior
I receive a 401 unauthorized. However, I can get it to work in postman and in the app. I can manually copy the bearer token from postman into the app and it works.

I also tried user.read, user.read.all, and the specific scope that the client SP is given permission on from the API principal. All combinations return a 401

I can also get it to work with this:

                var tenantId = _configuration["AzureAd:TenantId"];
                var clientId = _configuration["AzureAd:ClientId"];
                var clientSecret = _configuration["AzureAd:ClientSecret"];
                var resource = _configuration["CallApi:Resource"];

                HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, $"https://login.microsoftonline.com/{tenantId}/oauth2/token");
                req.Headers.Add("Accept", "*/*");
                req.Content = new StringContent(string.Empty, Encoding.UTF8, "application/x-www-form-urlencoded");

                // This is the important part:
                req.Content = new FormUrlEncodedContent(new Dictionary<string, string>
                {
                    { "grant_type", "client_credentials" },
                    { "client_id", $"{clientId}" },
                    { "client_secret", $"{clientSecret}" },
                    { "resource", $"{resource}" }
                });

                HttpResponseMessage resp = await client.SendAsync(req);
                string body = await resp.Content.ReadAsStringAsync();
                JObject tok = JObject.Parse(body);

                var client2 = _clientFactory.CreateClient();


                client2.BaseAddress = new Uri(_configuration["CallApi:ApiBaseAddress"]);
                client2.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tok["access_token"].Value<string>());
                var response = await client2.GetStringAsync(url);
@snapfisher snapfisher changed the title [Bug] Unable to call AAUD Protected Azure Functions from ASP.Net Application [Bug] Unable to call AAD Protected Azure Functions from ASP.Net Application Feb 19, 2021
@jennyf19
Copy link
Collaborator

@snapfisher we have a protected Azure Function as one of our dev apps, which is called by this client -> appsettings and startup.cs. We use downstreamWebApi to handle calling a web API, in this case Graph.

The Azure Function was built from our Azure Functions template.

@snapfisher
Copy link
Author

snapfisher commented Feb 24, 2021 via email

@snapfisher
Copy link
Author

I see what you are doing here. My question is, is there anyway to use MSAL in a ASP.Net project, calling a function, where the function does not use your template or MSAL, but has OAuth turned on in the portal as part of the function app?

What is here seems good (I am assuming it will work), but does help me explain why the other does not work. Is it just not supported to use MSAL with Function App settings? Thx.

@snapfisher
Copy link
Author

snapfisher commented Feb 27, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants