Category: Uncategorized

OAUTH with Azure – The just make it work edition

What is this?

I do not know how many times I have looked for an article explaining the just make it work part of how to authenticate to Azure from an application calling an Azure API. I usually find myself in a very long article on scope and OAUTH vs OAUTH2 vs OpenID.

This is more for me as documentation and perhaps for you as well, and it will not go thru why you should configure anything in a particular way. It is just a make it work.

If you do not know how to create an App Registration (necessary for login) or how to get the information used below, I have created a post here.

The three stages of logging in

  1. Get the information you need.
  2. Login to get a Token
  3. Use the Token in an API-call.

Getting the information you need

You will need:

  1. A Client ID
  2. A Client Secret
  3. The Azure Tenant ID
  4. Know which resource you are using

The 1, 2 and 3

The Client ID and the Tenant ID you can get from the App Registration Overview page of your app.
file

The client secret is either something you previously saved or something you created. Take a look at my post. Click on "Create the App Secret" in the Table of contents at the top if you need more information on how to create a secret.

The resource

This is the only tricky part.

  • If you need to manipulate about 90% of Azure you use https://management.azure.com/
  • If you are login into Storage Account you should/could use https://storage.azure.com/

Postman

The number one client for calling and testing APIs.

Login to get a Token (with Postman)

Gather all the information you have above and lets get to configuring.
You can use variables and environment settings for these.

  • Set the URI to: https://login.microsoftonline.com/[Tenant ID Goes here]/oauth2/token
  • Set the verb to POST.
  • Set the format of the body to form-data
  • Fill in the data:
    • client_id: Your Client ID
    • client_secret: Your client secret (password)
    • resource: see heading just above this
    • grant_type: client_credentials
  • Click Send and receive your access-token.
    file

    Bonus content for Postman

    If you want to be fancy, add a script to the test part and assign the token to a local variable for use in other calls.

    pm.test(pm.info.requestName, () => {
    pm.response.to.not.be.error;
    pm.response.to.not.have.jsonBody('error');
    });
    pm.environment.set("<your variable>", pm.response.json().access_token);

    Use the token in the API-call (with Postman)

    Now that you have your token, you can use it in other calls.

  • Simply click Authorization
  • In the dropdown select Bearer Token and paste your token in the token-field to the right.
    If you used the fancy script, use the variable instead.
    file
  • Done!

PowerShell

If clients scare you and you like using scripts to call APIs and execute stuff, you can use PowerShell.

Login to get a token (with PowerShell)

Doing this with PowerShell is even easier, once you know what and how to call stuff, all the code below is located in the same file.
Gather all the information you have above.

# Fill in the data in a collection
authBody = @{
    'Client_Id' = 'Your Client ID'
    'client_Secret' = 'Your client secret (password)'
    'resource' = 'see previous heading about this'
    'grant_type' = 'client_credentials'
}tenantId = 'Your Tenant GUID'
# Set the URI
tokenUri = "https://login.microsoftonline.com/(tenantId)/oauth2/token"

# Login to get a Token 
# Notice -ContentType and -Formresult = Invoke-RestMethod -Uri tokenUri -ContentType "multipart/form-data" -FormauthBody -Method Post

# A token must be a SecureString when used in later API-calls.
secureToken = ConvertTo-SecureStringresult."access_token" –asplaintext –force

Are you using Windows PowerShell?

If you need to use Windows PowerShell, aka 5.1, you need to replace the Invoke-RestMethod line with:

Invoke-RestMethod -Uri tokenUri -Method Post -BodyauthBody

Note the lack the -Form parameter and -ContentType

Use the token in the API-call (with PowerShell)

When you have your $secureToken you can use it in any API call as a bearer-token.

# Use the token in the API-call
uri = 'https://your api call'response = Invoke-RestMethod -Authentication Bearer -Token secureToken -Uriuri 

Done!

Bonus content on the Token

Did you know that the Token contains information that you can parse? I sure did not.
Visit eiter https://www.jsonwebtoken.io/ or https://jwt.io/ to see the information in the token. You simply paste your token and see what it contains.
Here is an example of a payload for the token I got in Postman:

{
 "aud": "https://management.azure.com/",
 "iss": "https://sts.windows.net/<tenantGUID>/",
 "iat": 1591799017, <-- Issued At
 "nbf": 1591799017, <-- nbf means not before
 "exp": 1591802917, <-- The expiration time in Unix timestamp
 "aio": "42dgYDhp4Pl5Eccb7me1ixxx",
 "appid": "<client ID>",
 "appidacr": "1",
 "idp": "https://sts.windows.net/<tenantGUID>/",
 "oid": "ad049d62-472f-4835-90be-qqqwwwee",
 "rh": "0.AQwAHo4e6q_ta0SWTzChaFpEhgeZB<<<<>>>>>.",
 "sub": "ad049d62-472f-4835-90be-<<<<>>>>",
 "tid": "<tenantGUID>",
 "uti": "HZ0eFQf0akCeUE0hJPgjAA",
 "ver": "1.0"
}

This information can be very useful. The aud (Audiance) should be the same as the resource setting and that might be different in your scenario.

Setting up an App Registration in Azure – The just make it work edition

What is this?

There are a lot of articles out there on how to setup an App Registration in Azure. Most of them contains a lot of useful information on why, rather than how.

This article is only about the how.

What you need to do

  1. Log into Azure
  2. Find the App Registration page.
  3. Create the App registration
  4. Create the App Secret
  5. Where to find information you will probably need later.

The process

Login to Azure

Come on you know this. Why are you even reading this step?

Find the App Registration Page

The easiest way of doing this is to use the search field at the top of the page. Just type App Reg and it should pop up.
file
Select it.

Create the App Registration

On the start page for App Registration, click New Registration at the top left.

  • Give it a useful name. Better than MyDemoApp
  • Make sure the top radio button is selected.
  • Leave the Redirect URI blank and click the Register Button
    file

Create the App Secret

Remember to store the secret somewhere!!!
When you have registered your app you will be forwarded to its starting page.

  • In the menu to the left, select Certificates & secrets
  • In the new page, click the New client secret button.
  • Give it a description and expiration (I always use 1 year for test and dev keys) and click Add.
    file
  • Important! Take it slow!
  • Copy the value of the key created. This is the only time it is shown.
    file
  • Store the key for later use.

Where to find information you will probably need later

When using this App to log in or authenticate you will use additional information, beside the Client Secret.

  • Go to the start page for the App Registration and choose your App.
  • In the start page of your app you will find everything you usually need
  • Here you will find the Client ID (under Application (Client) ID) and
  • Tenant ID, which you need to get a token.
    file

YouTube Session on Data center redundancy

The session

I am a co-admin of the Azure Meetup Stockholm group. We usually host sessions on anything Azure related at an office and usually in the evening. Due to the current situation, corona, we decided to move the sessions to YouTube. I did my first session this Monday (1st of June 2020).

The session is on how you can achieve full redundancy between different Azure data centers in the event of an outage, the challenges this poses and a proposed solution. It also contains a fair bit on more hard core computer science, trying to explain why it is impossible to reach 100%.

Session link.

Bob

Strange error when connecting to DataLake using the APIs

This request is not authorized to perform this operation using this permission?! WTF?!

The issue

You are using AAD with OAUTH to access Azure Storage, configured as a DataLake. You get an error that looks like this:

This request is not authorized to perform this operation using this permission.

According to other sites the reason might bee that you have not added your user (or application) to the correct group, or according to others that the storage is configured with a firewall and lastly according to the official documentation it might be a malformed token among other things.

The solution

All those other reasons might be correct but I found another thing: The Datalake resource type is not registered for your subscription. I know, I do not know why you need to do that either but here goes.

The TLDR

Open the subscription on the root level, find resource providers and add Microsoft.DatalakeStore

The full story

The resource is not configured as usable from your subscription and it has to be enabled, or registered. This is the more hardcore way of not allowing certain services to be used in a subscription.

  1. Find the affected subscription. I usually use the menu on the left or search for it in the search-box.
  2. In the left menu of the subscription, scroll down to settings and find the "Resource providers" setting and click it
    file
  3. In the filterbox at the top of the list type datalake and you will get this list.
    file
  4. Select the Microsoft.DatalakeStore option. (Marked #2 in the picture)
  5. Click Register (Marked #3 in the picture). The picture is taken after the registration was done.
  6. Wait, done, retry your API-call.

There might be access issues with registering providers in a subscription. You have to be an Owner or a contributor to do it but the good news is that it only needs to be done once per subscription.

Basic walkthru setup of Azure Front Door with APIm

When I recently setup an Azure Front Door (AFD) I found that there was no good for dummies or just make it work kind of articles, and that is why I write this. That said, if you are looking for more in depth documentation I recommend this page, and if you are looking for an in depth example and setup with APIm you should check out this GitHub repo by Paolo Salvatore.

Finding AFD

The first task is to find Azure Front Door. I usually use the search bar at the top of the page and the select the marketplace option.

Configuring AFD

Basics

First you need to assign or create a resource group for the new AFD. Note that the location is only for the resource group and not the AFD. The ADF service is a global service and as such have no location. That is one of its prime features.

Note The location for my resource group in the picture is not valid. Choose any under Recommended in the dropdown.

Click the Next:Configuration button to continue.

Configuration

When you setup an AFD for the first time, you get a nice Wizard to help you along. Start by clicking the plus-sign under Frontend/Domains.


In this step you need to add a frontend host, which sounds tricky but is really only the web address that the AFD will have once you publish it. This name needs to be globally unique. I have chosen mikaelsandblog so the address will be http://mikaelsandblog.azurefd.net when I publish it.

The other two options are out of scope for this blogpost but they have no effect on what we are trying to do.

Backend pools

This is the second step. Just click the plus-sign again. Here you will add pointers to the APIm instances you want to expose using AFD. The name pool refers to the pool of service endpoints that AFD can pick from to direct an incoming call.

Name

Start by giving the pool a name, like MyAPIms or something. When you do this properly, you might want to use a better name.

Add a backend

Click on the + Add a backend link to get this form

In the dropdown, chose API Management. This populates the form with the APIm instances available to you in your subscriptions, which is awesome! Simply chose the subscription and APIm instance you want, and you would probably also leave the port configuration as they are.

Should you need to point to an instance which is not in the same subscription, you should use the Custom Host Option. Simply add the host FQDN for your APIm instance in the Backend host name field. In my case this is mikaelsand.azure-api.net and leave all the other settings as is.

Priority and weight

If you are looking for the simplest of setups you can skip this part.
In some scenarios these settings are really important. In my case I needed to demonstrate the use of AFD as a failover service. This meant that one APIm instance should always be preferred if it is available. The basic setting for priority and weight points to a round robin pattern where all endpoints are treated equally. In order to make one endpoint be the preferred I simply gave that one the max setting in both, so priority=1 and weight=1000 made sure that one APIm was called as often as possible.

If this is not in the scope of your scenario, just leave the settings as is.

Routing rules

The last step is to setup routing for your AFD. This is very useful if you have several services behind your AFD, but that is not the scope of this post. Simply click the plus sign and review the form.

The settings should be enough to get your first call thru, so simply click Add.

Provisioning

You should now be able to end the configuration of AFD and provision it from Azure. It will not even take a minute.

Testing it out

If you need some tips on how to make sure it works, you can keep reading.
To make sure that everything works as it is supposed to, you can fire up Postman or VS Code. First, try to call your APIm directly to know that everything is working as intended:

The call

GET https://mikaelsand.azure-api.net/echo/resource?param1=sample
Ocp-Apim-Subscription-Key: xyzxyzxyz

The response

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Expires: -1
Accept-Encoding: gzip,deflate
Host: echoapi.cloudapp.net
User-Agent: vscode-restclient
ocp-apim-subscription-key: xyzxyzxyz
X-Forwarded-For: 217.208.192.204
X-AspNet-Version: 4.0.30319
X-Powered-By: Azure API Management - http://api.azure.com/,ASP.NET
Date: Thu, 30 Apr 2020 09:06:33 GMT
Connection: close

Then you change the host address in the URI to the host address you assigned earlier. For me I replaced mikaelsand.azure-api.net with mikaelsandblog.azurefd.net. The you call the API once again.

The call

GET https://mikaelsandblog.azurefd.net/echo/resource?param1=sample
Ocp-Apim-Subscription-Key: xyzxyzxyz

The response

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Via: 1.1 Azure
Expires: -1
Accept-Encoding: gzip,deflate
Host: echoapi.cloudapp.net
User-Agent: vscode-restclient
ocp-apim-subscription-key: xyzxyzxyz
X-Forwarded-For: 217.208.192.204,147.243.71.16
X-Azure-ClientIP: 217.208.192.204
X-Azure-Ref: 0eZWqXgAAAAArCUZJElgDSJxnlGMAYizAU1RPRURHRTA4MTUAMGYyMTViODAtNjk3OS00YzU3LWIzM2ItOTYyODI3NjZiYjQ5
X-Forwarded-Host: mikaelsandblog.azurefd.net
X-Forwarded-Proto: https
X-Azure-RequestChain: hops=1
X-Azure-SocketIP: 217.208.192.204
X-Azure-FDID: 0f215b80-6979-4c57-b33b-96282766bb49
X-AspNet-Version: 4.0.30319
X-Powered-By: Azure API Management - http://api.azure.com/,ASP.NET
Date: Thu, 30 Apr 2020 09:08:09 GMT
Connection: close
Content-Length: 0

You should get the same answer back, with some additional headers. If you do, everything is working fine.
All those X-headers are set by AFD and can be used for tracking and debugging calls. The sample put up by Paolo examines this.

If you do not have access to any API in the APIm you are trying to call you can always your the status service we used under the health probe section above.

The call

GET https://mikaelsandblog.azurefd.net/status-0123456789ABCDEF

The response

HTTP/1.1 200 Service Operational
Content-Type: application/json
X-Azure-Ref: 0PJqqXgAAAACTmVtpuYfiQqT3XHQhG9jLU1RPRURHRTA4MjIAMGYyMTViODAtNjk3OS00YzU3LWIzM2ItOTYyODI3NjZiYjQ5
Date: Thu, 30 Apr 2020 09:28:28 GMT
Connection: close
Content-Length: 0

In closing

There are a lot of nice and useful features in AFD. I suggest that the next thing you look at are routing rules or custom domains.

If you want to get your teeth into it, I think the best place to start is the AFD FAQ.