For most people, using PowerShell scripts/cmdlets to access Azure and get information about subscriptions and resources (e.g. Logic Apps) will be enough.
But what if you want to do it yourself from .NET?
Luckily there are some good management libraries you can use. However, there aren't a huge amount of samples out there on how to use those management libraries.
So I thought I'd provide a guide on how to do the following: Log into Azure, get a list of subscriptions, select a subscription, and then get a list of LogicApps associated with that subscription.
The second part of this I covered in an earlier post on how to use the Logic Apps Management SDK. But I soon discovered that the Azure Management Libraries and the Logic Apps Management Library use a slightly different credential format.
The Demo App
Here's what the app we're creating is going to look like:
1) How to login
Normally when you login to Azure, you have to know what AAD Tenant to authenticate against (see the sidebar below for an overview of AAD and tenants).
However, Azure has the concept of a multi-tenant login i.e. a login where you don't know which AAD Tenant you're using: so you login using the common tenant.
When you login, you have to specify the ID of the client you're using. Normally in AAD you'd set up a client in your directory, and then authenticate against the access rights given to that client.
This obviously wouldn't work for a common tenant, so in the special case of the common tenant, Azure has a list of common clients you can use. One of these is the PowerShell client: when we use this client id, Azure assumes that we're a PowerShell script trying to authenticate against Azure (you can see this in the login window, as it will say
Sign in to Microsoft Azure PowerShell
in the window title).
Logging in using the common tenant gives us limited permissions, but one of the things we *can* do is get a list of the subscriptions that the current user can access.
Logging in is as simple as running this code:
result = authenticationContext.AcquireToken(
What is returned to us is an
object that will have a JWT (aka Bearer Token) in the
property (see the sidebar later for an explanation of JWTs/Bearer Tokens).
is what we pass to our Management Library method calls, and later to our LogicApps SDK methods calls.
2) How to get a list of subscriptions
Luckily, with the Management Library, this is really easy:
// Project subscriptions into a list of SubscriptionWrapper instances
> subscriptions = response.Subscriptions.Select
There are three main parts to the code above:
3) How to get a list of Logic Apps
Getting a list of LogicApps is simple too - all we need is our
, and the ID of a subscription.
We get the user to select a subscription from the list we obtained in the previous step, and then execute this code:
client.SubscriptionId = subscription.SubscriptionId;
> workflowPage = client.Workflows.ListBySubscription();
> workflows = workflowPage.ToList();
Here, we're doing the following:
So far, so good.
But if you were to try and execute the above code using the common tenant
we obtained in Step 1) you may find yourself getting this error:
The full error text is:
"The access token is from the wrong issuer 'https://sts.windows.net//'. It must match the tenant 'https://sts.windows.net//' associated with this subscription. Please use the authority (URL) 'https://login.windows.net/' to get the token. Note, if the subscription is transferred to another tenant there is no impact to the services, but information about new tenant could take time to propagate (up to an hour). If you just transferred your subscription and see this error message, please try back later."
The reason for this is simple: we authenticated against the common tenant, but now we're trying access data from a subscription which belongs to a separate tenant - and we don't have an
for this new tenant.
What we have to do in this case is acquire a new
(a JWT) for the same user and client ID, but authorising against the tenant for the subscription we selected.
i.e. we have an
, but it's a common tenant
, and therefore is limited in what is authorised: to work with resources that are specific to a particular subscription, we now need an
for that specific subscription and tenant.
[Note: if we didn't need to supply a list of subscriptions, and new the subscription id and tenant id all along, we wouldn't even need to sign in using the common tenant].
To do this, we just need to run the code in Step 1) again, but this time instead of using a
of "common", we use the
of the subscription the User selected.
Running the code from Step 1) again will cause the login box to appear again, but in most cases it will flash up blank, and then disappear, as long as it detects that your common tenant credentials are valid for the new tenant.
Note: You may notice that when you use the portal, and you log in, and then change your subscription, you don't see a login box: that's because there's a way to refresh your current
for the new tenant without going via the standard login route. I'll cover this in a later post.
4) How to logoff
Logging off should be really simple. But again, like most things in Azure when you have multiple accounts, it's not.
To log off for a given
(i.e. a given login) you have to do the following:
The thing is, you can be logged into multiple tenants at the same time.
Personally, I think the logout functionality is a bit messy, although I suspect it's just that it needs to be surfaced properly in an API or REST call.
This is the code that needs to be executed. The
needs to be the one you created to login with (i.e. the one you put the
into). The code for clearing the Cookies comes from the source code for the
in GitHub (
- hat tip to
Poul K. Sørensen
for finding it first!):
INTERNET_OPTION_END_BROWSER_SESSION = 42;
, SetLastError =
And that's it.
Well, there's a bit more: you should cache the
for each Tenant you login to so you don't login more than once.
Here's a link to the sample code - it's a VS2015 project. It's not production quality code (hey, it's a WinForm app! How retro!) but it does the job and gives you an idea of how to do this yourself. Also, to keep the size down, I didn't include the NuGet packages, so when you first open it it will attempt to download them all (or go to Tools/NuGet Packaage Manager/Manage NuGet Packages for Solution to download them) - it won't compile without them:
DemoGetSubscriptionsAndLogicApps v1.0.zip (18.29 KB)
Any problems, let me know - I can't guarantee it'll work for all scenarios.
Here's some useful information that should help you understand how all of this works under the covers.
What "logging into Azure" means
When you log into Azure, you're logging into Azure Active Directory (AAD) - either one you host (in your subscription) or a common one (e.g. O365).
Technically, you're using an AAD Tenant: A tenant is an instance of Azure Active Directory just for your organisation (basically the same meaning when we talk about
in multi-threaded programming): when you create an O365 Enterprise subscription you get assigned a tenant, as you do when you create an Azure subscription [I'm simplifying this a great deal, as it's really a rather complex subject - see this post here
, or see Vittorio's post
, or Brady's post
for more detail).
When you create a personal Azure Subscription, an AAD tenant is created for you, and within that AAD is a default directory - that's right, it's an Azure Active Directory Directory!
The default directory will use a name related to your Microsoft Account Name e.g. if your Microsoft Account is email@example.com, your default directory will be
You can create multiple AAD Directories from within the management portal - an AAD Directory doesn't belong to any subscription.
A subscription can only use one directory at a time - you can see what directory is being used by going to the Settings view in the old portal.
: if you have an Enterprise O365 account, you can link the AAD tenant for your O365 account to your Azure subscription, and then tell that subscription to use the O365 directory for authentication - which means your corporate users can log in to the Azure subscription.
Because we're using the management libraries, we're using the
protocol for logging in - which means that when we successfully, authenticate, we're given a
token in JWT form (pronounced "jot"), which is stored in a cookie locally against the id of the client we authenticated against.
A JWT (JSON Web Token - see
for more info, and for a decoder:
) is a string comprised of three Base64 encoded sections, separated by full stops/period (.). You can decode these section to see what they contain - the important bits are who has been authenticated, and when the JWT expires.
When we authenticate (using the Azure login window) we're passed one of these Bearer tokens, and we have to then transform it into a Credentials object for use by the Management libraries.
Note that if you were using the REST interface (which is what the Management libraries use underneath) you'd be passing the Bearer token in the HTTP header for each request.
Two types of Azure Account
There are currently two types of Azure account:
Why is this important? Azure needs to know what type of account you have, so it can work out which AAD Tenant to authenticate you against.
When you attempt to login to an Azure resource e.g. the management portal, you'll sometimes see this screen:
(it used to have a password box under it, and when you tabbed out of the email address box, it would start doing something, but recently they've started phasing out that version and started using the version above).
The reason this screen exists is to allow Azure to work out if you have an
- you're then directed to the appropriate login screen:
can customise their login screen.
If you happen to have an
with the same name, then you'll see this screen next:
This is Azure's way of saying that it can't work out which of the two accounts you wish to use.
Some services only allow you to use a
to login - this will be obvious on the login screen:
The bane of those with multiple accounts: Auto Logon
One thing that those people with multiple Azure accounts (both
) hate with a passion (well, I do!!) is auto logon: you go a secured resource (e.g. Azure Portal), click the
button (or just type in the page URL), and instead of being asked which account you want to use, you're just logged in with what seems like a random account.
Why does this happen? It's to do with how Azure AD has grown over time, and how something that is designed to make life easier for people with single accounts tends to make it more complex for those with multiple accounts.
Firstly, there's the "Keep me signed in" feature: if you see this checkbox on a login screen, and tick it, a cookie is created locally which stores your authentication token.
Next time you go access a secured resource or click the SignIn button, as long as the authentication token is still valid, then you're automatically logged in using that account.
But… if you then login using another account, and *don't* tick the same option, and then close your browser, and then try and login again, instead of logging you in with the previously used account, you're logged in with the original account (i.e. the one you ticked the option for).
It gets more complex when you realise that whilst only a single
can be marked for auto-login at a single time, multiple Corporate Accounts can be marked for auto-login at the same time.
I mention this because when it comes to logging in from code, you can actually control this functionality and (hopefully) give your end user a more pleasant login experience.
How to login to Azure if you don't know the tenant
With all the discussion above, it may not be obvious on how to login to Azure if you don't know which AAD Tenant to authenticate against.
The solution is that Azure provides for the concept of a common tenant: the common tenant indicates that you don't know which tenant should be used (and you don't actually care): Azure will log you in against the relevant tenant for the user signing in. After the user has logged in, you can get the tenant details (should you need them).
In Step 1, where we login, note the use of a variable called
: this lets us control whether or not we wish to see the login window if we're already logged in.
This value is an enum called
, and has the following values and meanings:
The user will be prompted for credentials even if there is a token that meets the requirements already in the cache.
Acquire token will prompt the user for credentials only when necessary. If a token that meets the requirements is already cached then the user will not be prompted.
The user will not be prompted for credentials. If prompting is necessary then the AcquireToken request will fail.
Re-authorizes (through displaying webview) the resource usage, making sure that the resulting access token contains updated claims. If user logon cookies are available, the user will not be asked for credentials again and the logon dialog will dismiss automatically.
In our case, we want to use
when we first login (in case we have a token that can be reused) but want to set it to Always when we Log off (so that we're prompted to login next time we login). There are some flaws in this plan: since we're using the PowerShell client ID, if you logged into PowerShell recently, and chosen the "keep me logged in" option, then when you run this tool, you'll be auto logged in as the user you logged in to PowerShell with. The only way around this (that I know of at the moment) is to use a different client id.
Powered by: newtelligence dasBlog 2.3.12105.0
The opinions expressed herein are my own personal opinions and do
not represent my employer's view in any way.
Theme design by Jelle Druyts