Hi guys im following the next tutorial from azure:
https://learn.microsoft.com/en-us/rest/api/apimanagement/current-ga/subscription/create-or-update?tabs=HTTP&tryIt=true&source=docs [Azure create or update suscriptions]
I already made it work,but i dont know from where comes from the Bearer token that the example uses
Can anybody explain to me how i can get that bearer token? actually im planning to use this to create api keys from the back end but i dont exactly know from where i can request that bearer token.
I know it says "Azure Active Directory OAuth2 Flow" in the part of security but can anyone explain to me how that works?
you can get the bearer token by following commands in postman:
post https://login.microsoftonline.com/**{tenantid}**/oauth2/token
From your application you can get the tenant id and client id
Azure portal ->Azure active directory ->your app->overview
client secret:
When you send the command you can get the bearer token.
Reference:
Azure REST API: Create Bearer Token - cloudopszone.com
Alternatively, you can generate the Bearer token/access token using cloud shell from the portal by following the below steps
Sign-in to the Azure portal (https://portal.azure.com)
Open cloud shell, select Power Shell
If you have multiple subscription, using set-Azcontext cmdlet set a particular subscription as context to perform operation on that subscription.
Run the cmdlet Get-AzAccessToken this will give you the access token.
Here is the sample output for reference:
I am currently using OpenIdConnect to execute HTTP GET requests for my Azure B2C custom policies. For example here is the Unified SignInSignUp:
public static void Unified(HttpRequest Request, HttpResponse Response)
{
string nonce = "defaultNonce";
string clientID = ConfigurationManager.AppSettings["aad.clientid"];
string authUrl = ConfigurationManager.AppSettings["aad.authUrl"];
string redirectUri = ConfigurationManager.AppSettings["aad.redirecturi"];
string unifiedPolicy = ConfigurationManager.AppSettings["aad.unifiedPolicy"];
// build url for AAD auth and redirect to ourself
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}?", authUrl);
sb.AppendFormat("p={0}", unifiedPolicy);
sb.AppendFormat("&client_id={0}", clientID);
sb.AppendFormat("&redirect_uri={0}", redirectUri);
sb.AppendFormat("&nonce={0}", nonce);
sb.AppendFormat("&scope=openid");
sb.AppendFormat("&response_type=id_token");
sb.AppendFormat("&prompt=login");
sb.AppendFormat("&response_mode=form_post");
// redirect to auth via AAD (and then redirect back to ourself)
Response.Redirect(sb.ToString(), true);
}
I would like to use MSAL instead but am having trouble finding a C# .NET sample that executes an HTTP GET request like I am doing with OpenIdConnect. My current technique returns the id_token just fine, but I would like to take advantage of MSAL's capabilities like caching etc.
Is such a sample around?
I wanted to add this as a comment, but the system indicated it was too long. So I would like to answer my question, since I did find some sample code (mentioned in my comment to self above) that helped me get started ~using~ MSAL.net. However I am having a number of issues (e.g. when I call my edit profile custom policy the set of claims I get is are very incomplete, using OpenIdConnect I get all my claims) and questions and will probably post another questions that is more specific, laying out my requirements. I really just need the id_token (and the OpenId Connect code I posted above was great for that), not the access or refresh tokens, and all I really need to do is validate that id_token and implement a KMSI (keep me signed in) strategy. I have added the B2C KMSI in my custom sign-in policy, but can't see how to query it in my web (asp.net web forms) web project. Currently (without using Azure) I have a "remember me" checkbox on my website and I write a persistent cookie with a rolling 30-day expiry with encrypted data in it and everything works as required; I am trying to move to Azure B2C and keep that all working.Also for validating the token I am currently using some code I found in a post here that uses low-level code (System.Security.Cryptography namespace) and it validates well, but I don't see how to validate the few claims that are recommended in documentation I have seen. So I will create a new post that inquires about all that. Thanks.
I'm working with a .Net Core Web API and a .Net Core Web MVC Application. They both use Azure AD B2C to authenticate users. But in order to get a response from a HttpRequest from the Web API I need to provide the JWT Access Token from B2C for the signed in user on my web MVC application. Is there a way to obtain this access token inside a controller using the authenticated "User".
I have tried accessing the claims of the signed in user but no luck there, I have also used jwt.ms to review that the B2C workflow works well and that the JWT token is being generated and it works as well. The MVC application is authenticating the user and the web API is working fine with a hardcoded token. I just need to obtain the access token from a signed in user rather than doing it hardcoded.
I expect to be able to get the B2C JWT access token so that I can later on pass it to the Web Api and be able to secure my requests.
After getting some help from the MS AzureADB2C.UI GitHub crew we were able to solve the issue. The issue was that the tokens aren't saved by default on the library, so we needed to configure OIDC to specify that the tokens have to be saved for future use within the application. And so here is the example code of the "Startup" configuration and the example of how to query the "JWT access token" from the controller.
Startup.cs:
services.Configure(AzureADB2CDefaults.OpenIdScheme, options => {
options.SaveTokens = true;
});
Controller:
string idToken = await HttpContext.GetTokenAsync("id_token");
More information on how was the issue solved can be found on the following link:
https://github.com/aspnet/AspNetCore/issues/11424
You can refer to this sample application.
It uses the ASP.NET Core Azure AD B2C middleware to authenticate the end user and MSAL.NET to acquire, cache, and refresh the access token.
The access token is acquired in the AzureADB2COpenIdConnectOptionsConfigurator class.
A code example for a controller method referencing the access token is here.
Is it the actual token string you need? If so, you can access the headers using the HttpContext within the controller? The HttpContext will have a collection of headers that were passed in
I have a very simple Azure function in C# for which I've setup Azure AD Auth. I've just used the Express settings to create an App registration in the Function configuration.
public static class IsAuthenticated
{
[FunctionName("IsAuthenticated")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "options", Route = null)]
HttpRequest req,
ILogger log)
{
return new OkObjectResult("You are " + req.HttpContext.User.Identity.Name);
}
}
When I access the function in my browser everything works as expected (if not logged in I have to login and get redirected to my API). But if I try to access my function anywhere a Bearer token is needed I get an 401 Unauthorized error. Even weirder I also can't execute the function in the Azure Portal.
But the token was aquired without a problem and added to the request:
I've tried a few different things to solve this problem. First I thought maybe it's a CORS problem (since I've also had a few of those) and just set CORS to accept *, but nothing changed.
Then I've added my API login endpoints to the redirect and tried setting the implicit grant to also accept Access tokens, it's still not working.
Is there anything I've overlooked? Shouldn't the App registration express config just work with azure functions?
EDIT:
Putting the URL to my function app in the redirects as suggested by #thomas-schreiter didn't change anything (I've tried the config in the screenshot and also just putting each of those values on it's own).
EDIT 2:
I've now also tried to aquire an Bearer token the manual way with Postman, but I still run into a 401 when calling my API.
UPDATE 2020-05-12: According to ambrose-leung's answer further below you can now add a custom issuer URL which should potentially enable you to use v2 tokens. I haven't tried this myself, but maybe this will provide useful for someone in the future. (If his answer helped you please give him an upvote and maybe leave a comment 😉)
This took forever to figure out, and there is very little information about this in the offical documentations.
But it turns out the problem was/is that Azure Functions don't support Bearer tokens generated by the oauth2/v2.0/ Azure API. Since the portal uses those (if your AD supports them) you are out of luck to be able to run the function in there.
This also explains why my postman requests didn't work, because I was also using the v2 api. After switching to v1 I could access my API (Postman doesn't allow you to add a resource_id when you use the integrated auth feature, so I had to switch to handling everything manually).
After that came the realisation that you can't use MSAL either if you are writing a JS client (Angular in my case). So one alternative is ADAL, where the Angular implementation looks kind of awkward. So I decided to use angular-oauth2-oidc which took another hour of tinkering to get it to play nicely with Azure AD.
But after all that I can finally access my API.
I really don't understand why you wouldn't allow users to access Azure Function Apps with Azure AD v2 tokens, but at least this should be so much better documented. But whatever, I can finally go to sleep.
EDIT: After I opend an issue for this, they added a note that v2 isn't supported by Azure Functions, hopefully making life easier for other people.
https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad
I managed to get it working through postman using following configuration.
Important lesson was setting in "Allowed token audiences" and "resource" name used in postman to acquire token should be same in this case. I used the same code provided here in question. in this case app registered in Azure AD is a client and resource as well. configuration and testing through postman as follows
Acquire token in postman
Calling azure function using Postman .. Authorization header with bearer token
You can now use v2.0 tokens!
Instead of choosing 'Express' when you configure AAD, you have to choose 'Advance' and add the /v2.0 part at the end of the URL.
This is the code that I use in my console app to present the user with a login prompt, then take the bearer token for use with the Azure Function.
string[] scopes = new string[] { "profile", "email", "openid" };
string ClientId = [clientId of Azure Function];
string Tenant = [tenantId];
string Instance = "https://login.microsoftonline.com/";
var _clientApp = PublicClientApplicationBuilder.Create(ClientId)
.WithAuthority($"{Instance}{Tenant}")
.WithDefaultRedirectUri()
.Build();
var accounts = _clientApp.GetAccountsAsync().Result;
var authResult = _clientApp.AcquireTokenInteractive(scopes)
.WithAccount(accounts.FirstOrDefault())
.WithPrompt(Prompt.SelectAccount)
.ExecuteAsync().Result;
var bearerTokenForAzureFunction = authResult.IdToken;
When setting up your Active Directory authentication on your Function App, set management mode to advanced and fill in the Client ID and Issuer URL as required (and the client secret if necessary).
Importantly, under the Allowed Token Audiences, enter the Application ID URI. This can be found in your registered App Registration (in your AD) under the Expose an API option.
This is what I was missing to get authentication working on my Function App. Before I added that token audience, I would always get a 401 with a valid access token.
This Azure active directory - Allow token audiences helped me get my answer but it took me a while to realise what it was referring to. Remember, it's the Application ID URI that can be found within your App Registration.
I hope it helps!
If you are banging your head against the wall like myself and the original poster, it may be that you are allowing users to sign in from "Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)."
Note that as of May 2021, v2.0 works perfectly. If you use https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token to get a token with Postman (as described above), you will get a valid token that you can use to auth your AZ Function with.
With that said, IF a user is signed in via a personal account or an account not within your AAD, the token call made by MSAL is requested with the default Microsoft tenant id, NOT your tenant id.
THIS is why I was unable to auth my function. If you are logged in with a user in your tenant's AAD, MSAL is amazing and easy to use and everything will work as described in the documentation.
In the AAD app itself, go to Settings -> Reply URLs and verify that the url of the Function App is in the list, which has the following format: https://mycoolapp.azurewebsites.net. If it isn't, then add it.
If you use slots, you have to add it for both slots.
The only thing i can think of right now is Allowed Audience.
Go to Your Active directory settings and click Advance. Under Allowed Token Audience
Add your exact function url. It might already be there with call back url but Simply replace it with only function base url without any call back as mentioned in the picture.
Make sure when you press ok , you also save your Authentication / Authorization setting to take effect and try again after 1min or so. I tested using PostMan and passing bearer token and it works !
I'm facing the exact same issue today. The issue turned out to be the resource id that I was passing when requesting the access token.
For example, initially I was requesting a token like this, using the function URL as the resource id:
AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync("https://myfunction.azurewebsites.net", "myClientAppIdGUID", new Uri("https://login.live.com/oauth20_desktop.srf"), new PlatformParameters(PromptBehavior.SelectAccount)).Result;
While this returned an access token, I was receiving a 401 unauthorized when using the access token to call my function api.
I changed my code to pass my function apps App Id as the resource:
AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync("myFunctionAppIdGUID", "myClientAppIdGUID", new Uri("https://login.live.com/oauth20_desktop.srf"), new PlatformParameters(PromptBehavior.SelectAccount)).Result;
Everything works fine now.
For me this was solved when I added the scope: [clientId]/.default
per this article
I created an Azure API App and set the [Authorize] attribute on my controller and published it to Azure. Then I registered an Auth0 app, providing the data from my AD app, following Auth0's documentation. When I test the connection on their site it works just fine. I can also log in fine in my app and retrieve the access token with:
var auth0 = new Auth0Client("myUrl", "myTenant");
var user = await auth0.LoginAsync();
var accessToken = user.IdToken;
However, when I make a request to my API, passing the access token in the Authorization header, it just throws an error 401 (Unauthorized). From what the documentation says, I was under the impression this is all that should be needed, and I've not found any information to suggest otherwise. Is there an additional step to linking these?
The Solution is to configure ur API to accept tokens by that issuer, like for example by using owin middleware app.UseJwtBearerAuthentication(). Glad I could help!