Unable to Connect or Debug to Visual Studio Android Emulator with Visual Studio 2017 RC

Unable to Connect or Debug to Visual Studio Android Emulator with Visual Studio 2017 RC

Now I do appreciate that running prerelease software comes with some risk and I’m also aware that emulators are hard to get working 100% right on every machine. Ever since I can remember there have been connectivity issues with Windows Mobile, Windows Phone and now Windows 10 Mobile emulators; whether connectivity meaning to the internet, the local machine or being able to debug an application. So, it came as no surprise that after rebuilding my computer and installing Visual Studio 2017 RC that my installation of the Visual Studio Android Emulator was semi-broken. Turns out I had two issues I needed to overcome.

When I attempted to launch the emulator, I got the following notice, saying that the Internet Connection needs to be configured – this is pretty typical for first run as Hyper-V needs to setup the virtual switches that the emulator image will use.

image

After clicking Yes, the emulator is launched and my application is deployed. Unfortunately when Visual Studio attempts to launch the application and attach the debugger, the application closes immediately. This is again an issues I’ve seen before and in fact it appears on the troubleshooting web page for the Android Emulator (https://msdn.microsoft.com/en-us/library/mt228282.aspx):

– After you’ve run the emulator image the first time, close the Android Emulator

– Open Hyper-V Manager

– Select the virtual machine that matches the emulator you were attempting to run (make sure it’s in the Off state), and click Settings

– Under Processor –> Compatibility –> check the “Migrate to a physical computer with a different processor version” checkbox

image

– Click OK

Important: Make sure you stop and restart the Hyper-V service, otherwise, for some reason the setting is lost the next time you run the emulator.

Having done this I can now deploy and run applications on the emulator. The next issue was that for some reason the emulator couldn’t access the internet. I took a look in the Virtual Switch Manager in Hyper-V Manager (click Virtual Switch Manager from the Actions list on the right side of the Hyper-V Manager management console) and there was only a single “Windows Phone Emulator Internal” switch.

image

I clicked on New virtual network switch, selected External Access and gave the switch a name:

image

Each emulator virtual machine needs to have access to both the internal and external switches, so after clicking OK to exit the Virtual Switch Manager, I clicked on the virtual machine that I want to assign the new virtual switch to. Make sure you’ve stopped the virtual machine (closing the Android emulator will do this). Click Settings, click Add Hardware and select Network Adapter and click Add.image

From the Virtual switch dropdown, select the virtual switch you just created (External Access in my case), and click OK.

image

Now launch the emulator (either via the Visual Studio Android Emulator interface that can be launched from the Start menu independently of Visual Studio, or by attempting to run an application from Visual Studio) and you should now have internet access – check via the web browser in the emulator if you’re in any doubt.

UseWindowsAzureActiveDirectoryBearerAuthentication v’s UseJwtBearerAuthentication for Authorization with Azure Active Directory for an ASP.NET Web API

UseWindowsAzureActiveDirectoryBearerAuthentication v’s UseJwtBearerAuthentication for Authorization with Azure Active Directory for an ASP.NET Web API

In my previous post, Securing a Web API using Azure Active Directory and OWIN, I covered how to authorize requests against Azure Active Directory using the UseWindowsAzureActiveDirectoryBearerAuthentication extension method in the OWN startup class. This extension method has been designed specifically for Azure Active Directory but if you think about it, the Authorization token is just a JWT token, so in theory you could take a much more generic approach to authorizing access by validating the JWT. This can be done using the UseJwtBearerAuthentication extension method.

There are a couple of steps to using the UseJwtBearerAuthentication extension method. Firstly, in order to validate the signature of the JWT, we’re going to need the public certificate that matches the key identifier contained in the JWT. In my post on Verifying Azure Active Directory JWT Tokens I cover how to examine the JWT using https://jwt.io in order to retrieve the kid, retrieve the openid configuration, locate the jwks uri, retrieve the keys and save out the key as a certificate. In the post I used the certificate (ie wrapping the raw key in —BEGIN—, —END— markers) to validate the JWT; in this case I’ve copied the contents into a text file which I’ve named azure.cer and added it to the root of my web project (making sure the build action is set to Content so it is deployed with the website).

The next thing to do is to remove the UseWindowsAzureActiveDirectoryBearerAuthentication extension method, replacing it with the following code.

var fileName = HostingEnvironment.MapPath(“~/”) + “azure.cer”;
var cert = new X509Certificate2(fileName);
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
    AllowedAudiences = new[] {ConfigurationManager.AppSettings[“ida:Audience”]},
    IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
    {
        new X509CertificateSecurityTokenProvider(ConfigurationManager.AppSettings[“ida:IssuerName”], cert)
    }
});

This code uses the azure.cer certificate file combined with the Audience and IssuerName which I’ve added to the web.config.

<add key=”ida:Audience” value=”a07aa09e-21b9-4e86-b269-a18903b5fe54″ />
<add key=”ida:IssuerName” value=”https://sts.windows.net/55cc17b5-7d2a-418e-86a6-277c54462485/” />

The Audience is the application id (aka client id) of the Azure application registration. The IssuerName needs to match to what appears in the JWT. Opening one of the tokens in https://jwt.io it’s the ISS value that you want to use as the IssuerName.
image

Now you can run the project and see that again the requests are validated to ensure they’re correctly signed.

Securing a Web API using Azure Active Directory and OWIN

Securing a Web API using Azure Active Directory and OWIN

In this post we’re going to look at how to use Azure Active Directory to secure a web api built using ASP.NET (full framework – we’ll come back to .NET Core in a future post). To get started I’m going to create a very vanilla web project using Visual Studio 2017. At this point VS2017 is still in RC and so you’ll get slightly different behaviour than what you’ll get using the Visual Studio 2015 templates. In actual fact the VS2015 templates seem to provide more in the way of out of the box support for OWIN. I ran into issues recently when I hadn’t realised what VS2015 was adding for me behind the scenes, so in this post I’ll endeavour not to assume anything or skip any steps along the way.

image

After creating the project, the first thing I always to is to run it and make sure the project has been correctly created from the template. In the case of a web application, I also take note of the startup url, in this case http://localhost:39063/. However, at this point I also realised that I should do the rest of this post following some semblance of best practice and do everything over SSL. Luckily, recent enhancements to IIS Express makes it simple to configure and support SSL with minimal fuss. In fact, all you need to do is select the web project node and press F4 (note, going to Properties in the shortcut menu brings up the main project properties pane, which is not what you’re after) to bring up the Properties window. At the bottom of the list of properties is the SSL Enabled and SSL URL, which is https://localhost:44331/. Take note of this url as we’ll need it in a minute.

image

To setup the Web API in order to authorize requests, I’m going to create a new application registration in Azure Active Directory. This time I need to select Web app / API from the Application Type dropdown. I’ll give it a Name (that will be shown in the Azure portal and when signing into use this resource) and I’ll enter the SSL address as the Sign-on URL. This URL will also be listed as one of the redirect URIs used during the sign in process. During debugging you can opt to do this over HTTP but I would discourage this as it’s no longer required.

image

After creating the application, take note of the Application Id of the newly created application. This is often referred to as the client id and will be used when authenticating a user for access to the web api.

Application Id (aka Client Id): a07aa09e-21b9-4e86-b269-a18903b5fe54

We’re done for the moment with Azure Active Directory, let’s turn to the web application we recently created. The authorization process for in-bound requests involves extracting the Authorization header and processing the bearer token to determine if the calling party should have access to the services. In order to do this for tokens issues by Azure AD I’ll add references to both the Microsoft.Own.Security.ActiveDirectory and Microsoft.Own.Host.SystemWeb packages.

image

Note: Adding these references takes a while! Make sure they’re completely finished before attempting to continue.

Depending on the project template, you may, or may not, already have a Startup.cs file in your project. If you don’t, add a new item based on the OWIN Startup class template

image

The code for this class should be kept relatively simple:

[assembly: OwinStartup(typeof(SampleWebApp.Startup))]
namespace SampleWebApp
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
}

Additionally, you’ll want to add another partial class file Startup.Auth.cs in the App_Start folder.

namespace SampleWebApp
{
    public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
        }
    }
}

And now we get to adding the middleware that will be used to process the authorization header

public void ConfigureAuth(IAppBuilder app)
{
    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
             Tenant = ConfigurationManager.AppSettings[“ida:Tenant”],
             TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
             {
                 ValidAudience = ConfigurationManager.AppSettings[“ida:Audience”]
             }
        });
}

This uses the configuration manager to extract the Tenant and Audience settings from the web.config (and subsequently the Azure portal settings when you publish to the cloud):

<add key=”ida:Audience” value=”a07aa09e-21b9-4e86-b269-a18903b5fe54″ />
<add key=”ida:Tenant” value=”nicksdemodir.onmicrosoft.com” />

The tenant is the Id, or in this case, the domain of the tenant where the application is registered. The Audience is the application Id of the application registered in Azure AD.

Warning: If you run the application now and get an error relating to a missing type, you may have to revert the Microsoft.Owin.Security.ActiveDirectory to the most recent v4 package. At the time of writing this post there seems to be an incompatibility between v5 and Owin.

Reference to type ‘TokenValidationParameters’ claims it is defined in ‘System.IdentityModel.Tokens.Jwt’, but it could not be found

Ok, we’re ready to try making requests. I’m going to use Fiddler but you can use any other tool that’s able to generate and send HTTP requests. The first attempt will be a GET request to https://localhost:44331/api/values which is one of the default controllers that was created from the project template. Depending on what your project template included, the valuescontroller may, or may not, have the Authorize attribute applied to it. If, like me, you didn’t have the Authorize attribute applied to the valuecontroller, you should get a valid response back to your HTTP request. In this case, you’re going to want to add security to the valuecontroller by adding the Authorize attributes:

[Authorize]
public class ValuesController : ApiController
{

Now, try making the request again – you should now get a 401 Unauthorized error. The body of the response should say:

{“Message”:”Authorization has been denied for this request.”}

Clearly this is the case since we didn’t send the Authorization header. This time, let’s add an Authorization header, with the word “Bearer” and a token consisting of random text:

Authorization: Bearer abcdefg

This should generate the same response. However, let’s start to look into this further. To get more diagnostic information, add the following to the web.config file for the project

<system.diagnostics>
  <switches>
    <add name=”Microsoft.Owin” value=”Verbose” />
  </switches>
</system.diagnostics>

Now when you make the request you should see more diagnostic information in the Output window in Visual Studio:

Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
System.ArgumentException: IDX10708: ‘System.IdentityModel.Tokens.JwtSecurityTokenHandler’ cannot read this string: ‘abcdefg’.
The string needs to be in compact JSON format, which is of the form: ‘<Base64UrlEncodedHeader>.<Base64UrlEncodedPayload>.<OPTIONAL, Base64UrlEncodedSignature>’.

As we should have predicted, the token we passed in isn’t a value Jwt – it’s not even valid JSON. Let’s fix this by generating an actual access token for this Web API. In a previous post I walked through manually the process of authenticating, retrieving an authorization code and then exchanging it for an access token. I’ll do the same here.

First I’m going to launch an authorization url in the browser and sign in using credentials from the nicksdemodir.onmicrosoft.com tenant:

https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/authorize?client_id=a07aa09e-21b9-4e86-b269-a18903b5fe54&response_type=code&redirect_uri=https://localhost:44331/

The authorization url is made up of various components:

nicksdemodir.onmicrosoft.com – This is the domain name of the tenant where the web application is registered with Azure AD. You can also use the tenant Id (guid format)

a07aa09e-21b9-4e86-b269-a18903b5fe54 – This is the application id of the application registration in Azure AD

code – This indicates that the response should be an authorization code

https://localhost:44331/  – This is the uri that the browser will be redirected back to, passing with it the code in the query string.

Make sure you have the web application running, otherwise the redirect uri won’t resolve at it may be hard to extract the code from the query string (depending on the browser). After signing in, you’ll be redirected back to your web application with a URL similar to (the code has been shortened for brevity):

https://localhost:44331/?code=zvrs_zz0…….05B_ggAA&session_state=ef2986b8-75bd-484a-b9b9-68f0e46ab569

The next thing to do is to prepare a POST request in your http tool of choice with the following:

URL: https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/token

Body: grant_type=authorization_code&client_id=a07aa09e-21b9-4e86-b269-a18903b5fe54&client_secret=c06kP0Q9ENGpZGbiZTqB1QQaZUWNe190mCittRMr&redirect_uri=https://localhost:44331/&code=zvrs_zz0…….05B_ggAA&resource=a07aa09e-21b9-4e86-b269-a18903b5fe54

The Body parameters are broken down as:

a07aa09e-21b9-4e86-b269-a18903b5fe54 – This is the application id of the application registration in Azure AD. It’s required as both the client_id and the resource, since we’re using the access token to access the web application itself.

c06kP0Q9ENGpZGbiZTqB1QQaZUWNe190mCittRMr – This is a private key (aka client secret) issued by the Azure AD application to ensure the security of token requests. I’ll come back to this in a second and show how to create one for your application.

https://localhost:44331/ – The redirect uri for the application – required here to verify the calling party as it has to align with what’s in Azure AD

zvrs_zz0…….05B_ggAA – This is the authorization code returned in the previous step

To generate the client secret in Azure AD simply click on the Keys tab within the details of the application registration. You can then create a new key by entering a description. The description is only seen by you, so give it a name that’s meaningful to you. Note that once you save the new key, you will only be shown the value of the key once. Once you leave the page, the value of the key will never been shown again.

image

The key created in the Azure AD should be used as the client secret when doing the authorization code to access token exchange.

The response to this POST should return JSON which includes and access token value. Add the access token to the authorization header:

Authorization: Bearer G1ZsPGjPF6qJO8Sd5HctnKqNk_8KDc-………Lpy9P8sDWdECziihaPWyseug9hgD119keoZuh4B

This should give you a 200 response with data. And there you have it – you’ve successfully secured your web api so that it requires the user to be authenticated using Azure Active Directory.

Improving the Azure Active Directory Sign-on Experience

Improving the Azure Active Directory Sign-on Experience

I was talking to a customer the other day and had to log into the Azure portal. Normally when I launch the portal I’m already signed in and I’m not prompted but for whatever reason this time I was prompted to authenticate. Doing this in front of the customer lead to three interesting discussions:

– Use of two factor authentication to secure sign in
– Separate global administrator account for primary organisation tenant
– Company branding for Azure AD sign in

Firstly, the use of two factor authentication (TFA) is a must requirement for anyone who is using the Azure portal – if you are an administrator of your organisation, please make sure you enforce this requirement for anyone accessing your tenant/directory/subscription. This applies to staff, contractors, guests etc who might be using your Azure portal or the Office 365 portal. In fact, in this day in age, I would be enforcing two factor authentication for all employees – note that Outlook and Skype for Business are still stuck in the dark-ages and don’t access TFA sign in. For these you’ll need to generate an application password (go to https://myapps.microsoft.com, click on your profile image in top right corner and select “Profile”, click through to “Additional security verification,” click on the “app passwords” tab and then click “Create” to generate an app password.

Ok, next is the use of a separate global administrator account – this is in part tied to the previous point about using TFA. If you’re a global administrator of your tenant and you enable TFA, you won’t be able to generate app passwords. This is essentially forcing you down the path of best practice, which is to have a separate account which is the global administrator for your tenant. If other people in your organisation need administrative permissions, you can do this on a user or role basis within the Azure portal – our preference is to assign permissions to a resource group but there is enough fidelity within the portal to control access at the level you desire.

The other thing we’ve also enforced is that we do not host any Azure resources in our primary tenant (ie in our case builttoroam.com). Given the importance of Office365 based services we felt it important that we isolate off any resources we create in Azure to make sure they’re completely independent of our primary tenant. The only exception to this is if we are building internal LOB applications (ie only apps for Built to Roam use) – for these we include the app registrations within the builttoroam.com tenant so that we can restrict sign in and at the same time deliver a great sign in experience for our employees. For example we’re using Facebook Workplace (https://workplace.fb.com/) – we configured this within the builttoroam.com tenant in Azure AD to allow for a SSO experience.

Now, onto the point of this post – the last thing that came out of signing into the portal in front of the customer was that they were startled when we went to sign into the portal and our company branding appeared. To illustrate, when you first land on the portal sign in page you see:

image

After entering my email address, the sign in page changes to incorporate the Built to Roam branding

image

This not only improves the perception (for internal and external users), it also gives everyone a sense of confidence that they’re signing into a legitimate Built to Roam service.

In order to set this up, you need to navigate to the Active Directory node in the Azure portal and click on the Company branding. If you’re using Office 365 you should already have access to this tab. However, if you’re not, you may need to sign up for Active Directory Premium – you can get started using the Premium trial:

image

Once you’ve opened the Company branding tab (if you have just activated the trial, you may need to wait a few minutes and/or sign out and back in again in order for the Company branding tab to open) you can click on the link to “Configure company branding now”

image

There are a number of options and images that you can configure:

image

After saving the changes, if you attempt to sign in, you’ll notice the new images/colours etc appear. In this case, you can see that the welcome text at the bottom of the sign in page has been changed to what I entered in the company branding tab. Unfortunately because I didn’t set the sign in page image, the default is used, so you can’t see the red (#FF0000) background I set – you can see glimpses of it if you resize the page. This can be fixed by simply uploading a transparent image.

image

The ability to customise the sign in experience is just one way to improve the experience for you staff and customers.

The Danger of Admin Consent for Applications

The Danger of Admin Consent for Applications

In the last couple of posts I covered the use of admin consent to grant permissions for an application to access more than simply data related to the signed in user:

Admin Consent for Permissions in Azure Active Directory

Making your Azure Active Directory application Multi-tenanted

In my initial post talking about admin consent I added the “Read directory data” to the set of permissions that the application would request. This permission, along with a number of other permissions for the Windows Azure Active Directory resource, have a green tick in the “Requires Admin” column.

image

It’s all to easy for developers, when setting up the permissions for an application to not think through what enabling permissions for an application does. When you enable permissions for an application, by ticking the box alongside the permission in the Azure AD application configuration (see previous) image, you are essentially saying that the application will be able to perform those actions after the user has signed in and provided consent – this is true regardless of what role the user belongs to within the organisation (the application can perform the same actions whether a receptionist or the CEO of an organisation is signed in).

The division between permissions that require admin consent, versus those that do not, usually are based on whether the permission is for an action that only administrators should be able to do, versus those that any user should be able to do. For example in the case of Windows Azure Active Directory all users should be able to sign in and read their profile, read the basic profile of all users in the directory and access the directory as the signed-in user – all of these do not require admin consent as they are either actions that pertain to the signed in user, or they are actions that all users should be able to perform. The last permission does permits more access control as elements within the directory can be secured so users/roles/groups can access them; if the user is accessing the directory as themselves, they’ll only be able to access objects that they have permissions on.

When I checked the box alongside the “Read directory data” permission, I was essentially saying that all users (assuming a global administrator had performed the admin consent) would be able to read all data in their organisation’s directory (see https://msdn.microsoft.com/en-us/library/azure/ad/graph/howto/azure-ad-graph-api-permission-scopes):

image

In order words, once someone has signed into the application, the access token granted to the application can be used to retrieve all directory data – ummm that’s starting to sound pretty scary. No imagine if I granted “Read and write directory data” permissions to the application. Now the access token can read and write directory data. Put this into the context of hackers who use social engineering to access low level employees, you can imagine it wouldn’t be hard for them to access this application in order to access employee information.

The moral of this post is DO NOT enable REQUIRES ADMIN permissions to any native application (unless you’re 100% sure you know what the implications are) – it’s way to easy to intercept access tokens and act on behalf of the user.

Making your Azure Active Directory application Multi-tenanted

Making your Azure Active Directory application Multi-tenanted

So far in my previous posts I’ve discussed signing into an application using Azure Active Directory (Azure AD) using a basic application registration in Azure AD. Last post we added some additional permissions that required administrator consent. However, up until now, only users in the same directory (aka tenant) that the application is registered in, can sign in. In the case of the sample application I’ve been working with, the application is registered to the nicksdemodir.onmicrosoft.com tenant, so only users belonging to that tenant can sign in eg [email protected]. If I attempt to sign in with an account from a different tenant, I run into a few issues, and depending on what type of account I sign in with, the error that is displayed varies.

I’ll start by signing in with a regular user account that belongs to a different tenant (in this case btro365dev.onmicrosoft.com). When I attempt to sign in with this account, everything seems to go well – I’m prompted to sign in; I successfully sign in; I’m returned to the application where the code is exchanged for an access token. However, when I attempt to use this access token I get a rather cryptic error about an “Unsupported token” eg:

{“odata.error”:{“code”:”Request_BadRequest”,”message”:{“lang”:”en”,”value”:”Unsupported token. Unable to initialize the authorization context.”},”requestId”:”86481ea2-79bd-461b-93ad-4f649286617a”,”date”:”2017-01-25T21:28:14″}}

This is actually less cryptic than it seems – essentially it’s saying that I’m attempting to present a token that the API can’t process. If you were to open the access token in https://jwt.io, you’d see that the token has been issued by the nicksdemodir.onmicrosoft.com tenant (actually you’d see the STS url that correlates to this tenant) for an account that doesn’t exist in that tenant (eg [email protected]). Whilst this is a legitimate access token, when you present it to the Graph API, it attempts to retrieve information about the user in the issuing tenant, which of course fails, since the user doesn’t exist there.

Ok, let’s see what happens if I attempt to launch the admin consent prompt. In this case, after I sign in (now using [email protected] which is a global administrator) I get a more useful error message saying “AADSTS50020: User account … does not exist in tenant”.

image

The reason this error message is useful is that it prompts me to think about what I’m attempting to do – I’ve been prompting the user to sign into the nicksdemodir.onmicrosoft.com tenant, which is fine if I’m a user that belongs to that tenant but since I’m attempting to use a different user, this is clearly not correct. So, the first step in making my application multi-tenanted is to change the authorization url that I’m directing the user to in order to sign in, to one that is more generic and will allow signing in by users from any tenant. This involves exchanging the “nicksdemodir.onmicrosoft.com” with “common” in the url – the following code shows how I adapted the code in my sample application to support urls that are single tenanted (ie AuthorizationUrl and AdminConsentUrl) as well as the multi-tenanted equivalent (ie MultiTenantAuthorizationUrl and MultiTenantAdminConsentUrl).

private string BaseAuthorizationUrl =>
    “
https://login.microsoftonline.com/{0}/oauth2/authorize?” +
    “client_id=40dba662-4c53-4154-a5cf-976473306060&” +
    “response_type=code&” +
    “redirect_uri=sample://callback&” +
    “nonce=1234&” +
    “resource=
https://graph.windows.net”;

private string AuthorizationUrl => string.Format(BaseAuthorizationUrl, “nicksdemodir.onmicrosoft.com”);

private string AdminConsentUrl => $”{AuthorizationUrl}&prompt=admin_consent”;
private string MultiTenantAuthorizationUrl => string.Format(BaseAuthorizationUrl, “common”);
private string MultiTenantAdminConsentUrl => $”{MultiTenantAuthorizationUrl}&prompt=admin_consent”;

For example:

Authorization url: https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/authorize?client_id=40dba662-4c53-4154-a5cf-976473306060&response_type=code&redirect_uri=sample://callback&nonce=1234&resource=https://graph.windows.net

Multi-tenant authorization url: https://login.microsoftonline.com/common/oauth2/authorize?client_id=40dba662-4c53-4154-a5cf-976473306060&response_type=code&redirect_uri=sample://callback&nonce=1234&resource=https://graph.windows.net

Attempting to sign in using the multi-tenant authorization url with an account that doesn’t belong to the nicksdemodir.onmicrosoft.com tenat now yields the following error:

image

This error seems to be correct, considering the application registration exists in the nicksdemodir.onmicrosoft.com tenant. Unfortunately it’s not very clear what you need to do in order to fix this issue – you can’t add the application to the btro365dev.onmicrosoft.com tenant, and even if you could, you wouldn’t want to have to manually do that for every tenant that you want to support. Luckily, there is a mechanism that allows Azure AD to essentially add the application to new tenants on an as required basis (similar to how applications are added to a users list of applications at https://myapps.microsoft.com as they consent to use of the application). In order for Azure AD to do this, the application registration has to be configured to support multiple tenants. Click on the Manifest button for the application registration in Azure AD – the property “availableToOtherTenants” should be set to true (default is false).

image

Now when we attempt to sign in (again with a non-global administrator user) we see a familiar error saying that the calling principal (ie the signed in user) doesn’t have permissions.

image

We know how to fix this from my previous post, the only difference is that we need to direct the user to the multi-tenant admin consent url eg

https://login.microsoftonline.com/common/oauth2/authorize?client_id=40dba662-4c53-4154-a5cf-976473306060&response_type=code&redirect_uri=sample://callback&nonce=1234&resource=https://graph.windows.net&prompt=admin_consent

The global administrator, after signing in, will again see the admin consent prompt – it’s worth pointing out here that it lists both the directory the user is signed into (ie BTR Office Dev – btro365dev.onmicrosoft.com) and the tenant that the application is published (ie registered) in (ie DemoDirectory – nicksdemodir.onmicrosoft.com).

image

Again, consenting will enable all users in the foreign tenant (ie btro365dev.onmicrosoft.com) to then access the application via the multi-tenant authorization url.

There is one last adjustment that has to be made, and that’s to the Token url. When exchanging the code for an access token, it’s important that the token url is also adjusted to be either single or multi-tenant. Previously the url included the tenant that the application was registered to ie nicksdemodir.onmicrosoft.com. This needs to be changed in the multi-tenant scenario to use “common”. In order to allow authorization to occur for both single and multi-tenant scenarios within the application, I needed a way to dynamically control the token url based on whether the user signed in via the single tenant or multi-tenant authorization url. Currently, all we get back when the user has signed in is a code which we need to exchange for an access token. Luckily, we can pass an additional parameter, “state,” into the authorization url, which will get passed back to the application along with the code – we can use this to determine which authorization url was used. I’m only going to adjust the multi-tenant authorization url as the application will treat the lack of state parameter to mean that the user was directed to the single tenant authorization url.

private string MultiTenantAuthorizationUrl => string.Format(BaseAuthorizationUrl, “common”) + “&state=multi”;
private string MultiTenantAdminConsentUrl => $”{MultiTenantAuthorizationUrl}&prompt=admin_consent”;

Now, the token url is updated based on the state parameter value:

private string BaseTokenUrl => “https://login.microsoftonline.com/{0}/oauth2/token”;
private string TokenUrl(bool isMulti)
{
    return string.Format(BaseTokenUrl, isMulti ? “common” : “nicksdemodir.onmicrosoft.com”);
}

var isMulti = uri?
                    .Split(‘?’).Skip(1).FirstOrDefault()?
                    .Split(‘&’).Select(q => q.Split(‘=’))
                    .Where(x => x.Length == 2 && x[0] == “state”)
                    .Select(x => x[1])
                    .FirstOrDefault() == “multi”;

var tokenUrl = TokenUrl(isMulti);

And that’s it – a user can sign in from any tenant (assuming the global administrator has signed in an consented) and retrieve information from the Azure Graph API.

Admin Consent for Permissions in Azure Active Directory

Admin Consent for Permissions in Azure Active Directory

In the previous posts I’ve discussed authenticating and authorizing a user with Azure Active Directory (Azure AD) using a basic application registration. All application registrations are given default permissions to access the Azure Graph API – this was used in my previous post to retrieve information about the signed in user. The default permission set is a delegated permission that allows the user to sign in and view their own profile. This can be viewed in the Azure portal by extending the Required permissions tab for the application.

image

In this post I’m going to extend this permission set to include the “Read directory data” permission. You’ll notice in the previous image that there is a green tick in the “Requires Admin” column. What this means is that in order for a regular user (ie a user that is not a global administrator for the tenant) to sign in, a global administrator must first sign in and consent to permission on behalf of the organisation. If a regular user attempts to sign in, they’ll be confronted with an error message such as:

image 

Essentially the error “AADSTS90093: Calling principal cannot consent due to lack of permissions” indicates that a global administrator needs to sign in an consent on behalf of the organisation before users can sign in. If a global administrator signs in, they’ll see a prompt where they can consent permissions – this is slightly confusing as it would imply that the administrator is consenting on behalf of the organisation. Unfortunately this is not the case, they’re only consenting for use by their account.

image

In order for a global administrator to consent on behalf of an organisation, so that all users can make use of the “admin consent” permissions, they have to be directed to a new sign in page with the parameter “prompt=admin_consent” set in the query. In other words, the admin consent url is exactly the same as the authorization url, except it has “&prompt=admin_consent” appended to the end.

https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/authorize?client_id=40dba662-4c53-4154-a5cf-976473306060&response_type=code&redirect_uri=sample://callback&nonce=1234&resource=https://graph.windows.net&prompt=admin_consent

The admin consent prompt looks slightly different to a regular consent prompt as it highlights that consent is going to be assigned for the entire organisation

image

As this is a one-off operation, a global administrator can either navigate to the url in the browser, or the application can have a separate button that would launch the url so that the admin can consent. After the global administrator has consented, user’s will still be prompted to consent but this is for the delegated permission. In the same way that user permissions can be revoked by going to https://myapps.microsoft.com and deleting the application entry, organisation permissions can be revoked by opening the Enterprise applications tab for the Active Directory in the Azure portal. Select the application you want to remove and click the Delete button.

image

After the global administrator has consented for the organisation, any user can then read the directory data (ie more than just their own profile).

Verifying Azure Active Directory JWT Tokens

Verifying Azure Active Directory JWT Tokens

When working with OAuth and Open ID Connect, there are times when you’ll want to inspect the contents of id, access or refresh tokens. The website https://jwt.io is useful as you can drop in the token in the pane on the left, and the site dynamically decodes the header, body and signature for the JWT.

image

Unfortunately by itself the signature on the JWT can’t be verified as the website doesn’t know what key to use to validate the signature. The header of the JWT does provide information about the algorithm used (ie RS256) and the id of the key used but this by itself isn’t enough to locate the key to be used.

image

As RS256 is a public/private key algorithm, there is a private key, which the issuer holds, and a public key which is available to anyone to access. The former is used to generate the signature for a JWT; the later can then be used to validate the signature. To find the public key to use to validate the signature I’ll start with the OpenID Connect configuration document, which is available for any tenant at:

https://login.microsoftonline.com/{tenantId}/.well-known/openid-configuration

eg https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/.well-known/openid-configuration

The returned configuration document contains an attribute, jwks_uri, which points at https://login.microsoftonline.com/common/discovery/keys

image

Loading the jwks_uri returns another JSON document which lists a number of keys. Now we can use the kid from the header of the JWT to identify which key to use, in this case the first key in the list.

image

Attempting to simply copy the x5c value from the list of keys into the Public Key or Certificate box on the jwt.io website will still not verify the signature of the JWT. In order to verify the signature, wrap the key in BEGIN and END CERTIFICATE markers as follows:

—–BEGIN CERTIFICATE—–
MIIDBTCCAe2gAwIBAgIQEsuEXXy6BbJCK3bMU6GZ/TANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE2MTEyNjAwMDAwMFoXDTE4MTEyNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd6Sq5aJ/zYB8AbWpQWNn+zcnadhcMYezFvPm85NH4VQohTm+FMo3IIJl6JASPSK13m9er3jgPXZuDkdrEDHsF+QMEvqmffS2wHh3tKzasw4U0jRTYB0HSCbmnw9HpUnv/UJ0X/athO2GRmL+KA2eSGmb4+5oOQCQ+qbaRXic/RkAOLIw1z63kRneLwduQMsFNJ8FZbWkQFj3TtF5SL13P2s/0PnrqwGD59zcbDu9oHOtciu0h++YhF5CWdWEIgafcZk9m+8eY12BKamvPdBnyfpz6GVTenJQe2M+AGz5RSNshvI976VUbBiaIeNzvzaG91m62kFWLRqE3igq6D02ECAwEAAaMhMB8wHQYDVR0OBBYEFAgoZ9HLgFxH2VFGP6PGc4nFizD2MA0GCSqGSIb3DQEBCwUAA4IBAQBSFXalwSJP/jihg04oJUMV2MTbuWtuFhdrdXiIye+UNc/RX02Q9rxd46BfGeKEBflUgNfEHgyEiWTSLAOSDK70vu+ceCVQCGIQPjnGyYOpm80qAj/DNWZujVcSTTV3KZjMFsBVP7miQowfJQ58u9h8yuJHNhPpB2vOFmNhm4uZq3ve529Xt51HdtQGG9+Z9n1DhObqzkbz8xEFjA+KdfcRsZXa14ZkpAOe35VgyY0f8x34Y0LPfibWcNpfp0AhxKzyqT1GRRlKTjiBA6WNJIJIEeqh/nfOnwM0UQKRnt+2qeV3u00a5lrvJtEy7nq+s7xYtpVAsCvn5T0U1/8IHkxt
—–END CERTIFICATE—–

Entering the wrapped key into the Public Key or Certificate box on the jwt.io website will successfully verify the signature of the JWT.

image

Authorizing Access to Resources using Azure Active Directory

Authorizing Access to Resources using Azure Active Directory

In my previous post I discussed authenticating a user using Azure Active Directory (Azure AD), returning an id_token that can be used to identify the user that has signed in. However, this token isn’t an access token and as such can’t be presented in order to access remote services. In this post I’m going to show how you can request an access token that can be presented in the Authorization header when calling a service. The workflow is very similar to the workflow to retrieve the id_token:

– User attempts to sign into an application

– Application launches the Authorize URL in an external browser (includes “resource” parameter in Authorize URL)

– User is directed to a Microsoft URL where they are prompted to sign in

– User signs in

– User is prompted to consent that the application can access the specified resource

– After sign in, the User is redirected back to the application via a custom protocol

– Application receives an authorization code

– Application performs a POST request to the Token URL in order to exchange authorization code for an access token

– Application receives the access token

– Application makes call to remote service, attaching the access token in the Authorization header

To demonstrate this workflow I’m going to adapt the sample application I created in my previous post in order to access the Azure Graph API. The sample application is already configured with access to the Azure Graph API – this is done by default for all application registrations. In order to request access to a resource, you need to know the url of the resource you want to access. In this case the url for the Azure Graph API is https://graph.windows.net.

In addition to including the resource url in the authorization url, the other change I need to make is to switch the response type from id_token to code. The updated authorization url is:

var  authorizationUrl=
    “https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/authorize?” +
    “client_id=40dba662-4c53-4154-a5cf-976473306060&” +
    “response_type=code&” +
    “redirect_uri=sample://callback&” +
    “nonce=1234&” +
    “resource=https://graph.windows.net“;

Launching this url in the external browser will again prompt the user to sign in (unless they have previously signed in for this application, such as if you followed my previous post) but rather than immediately being redirected back to the application, the user will see a consent prompt – you’ll note that similar to the sign in prompt, the name of the application specified in Azure AD is used when requesting permissions.

image

The other thing to note is that once you’ve consented permissions for the application, you won’t be prompted again – Azure AD remembers that you’ve granted permissions. Permissions can be revoked by going to https://myapps.microsoft.com, selecting the application and clicking Remove.

image

The same “Remove” option is available if you turn on the new look (it’s the same url to get there – https://myapps.microsoft.com)

image

After completing the sign in and consent workflow, the user is navigated back to the application using the custom protocol. This time, instead of an id_token, the application receives a code as part of the url:

sample://callback/?code=AQABAAAAAADRN…….L7YiQ7PIAA&session_state=ffffd83b-3820-489e-9f35-70e97d58fd04

Unlike the id_token, and as you’ll see soon, the access_token, the code is not a jwt token that you can interrogate for information about the signed in user. Instead the next step in the process is to do the code-token exchange to retrieve the required access token. This involves doing a POST request to the Token URL, passing parameters in the body of the request.

Token URL: https://login.microsoftonline.com/{tenantId}/oauth2/token

eg https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/token

The POST body needs to contain the following values:

var postBody = new Dictionary<string, string>
{
    {“grant_type”, “authorization_code”},
    {“client_id”, “40dba662-4c53-4154-a5cf-976473306060“},
    {“redirect_uri”, “sample://callback“},
    {“resource”, “https://graph.windows.net“},
    {“code”, code}
};

40dba662-4c53-4154-a5cf-976473306060 – This is the client id (aka application id) of the application registration in Azure AD

sample://callback – This is the redirect uri specified in the application registration

https://graph.windows.net – This is the resource that you’re requesting an access token for. Make sure this is the URL for the Azure Graph API, not to be confused with the Microsoft Graph API (https://graph.microsoft.com)

code – This is the actual code that is returned from the sign in process (ie don’t use the word “code”)

The resulting code for parsing the code from the application redirect, and then exchange for an access token is as follows:

protected override async void OnActivated(IActivatedEventArgs args)
{
    base.OnActivated(args);
    if (args.Kind == ActivationKind.Protocol)
    {
        var eventArgs = args as ProtocolActivatedEventArgs;

        var uri = eventArgs.Uri.AbsoluteUri;
        var code = uri?
                    .Split(‘?’).Skip(1).FirstOrDefault()?
                    .Split(‘&’).Select(q => q.Split(‘=’))
                            .Where(x=>x.Length==2 && x[0]==”code”)
                            .Select(x=>x[1])
                            .FirstOrDefault();

        var tokenUrl = “https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/token”;
        var postBody = new Dictionary<string, string>
        {
            {“grant_type”, “authorization_code”},
            {“client_id”, “40dba662-4c53-4154-a5cf-976473306060”},
            //{“redirect_uri”, “sample://callback”},
            {“resource”, “
https://graph.windows.net”},
            {“code”, code}
        };
        using (var client = new HttpClient())
        {
            var content = new FormUrlEncodedContent(postBody);
            var result = await client.PostAsync(tokenUrl, content);
            var resultContent = await result.Content.ReadAsStringAsync();
        }
    }
}

The resultContent variable will include a JSON string which consists of an access_token, refresh_token etc.

image

In order to extract the access_token, the resultContent can be deserialized to an entity:

public class TokenData
{
    public string expires_in { get; set; }
    public string access_token { get; set; }
    public string refresh_token { get; set; }
    public string id_token { get; set; }
}

var resultContent = await result.Content.ReadAsStringAsync();
var token =  JsonConvert.DeserializeObject<TokenData>(resultContent);

Finally, the token.access_token value can be used to make a call to the Azure Graph API:

var graphUri = “https://graph.windows.net/me?api-version=1.6″;
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Bearer”,token.access_token);
var graphProfile = await client.GetStringAsync(graphUri);

The following screenshot shows the resulting profile information that’s returned from the Graph API

image

Note that the access token is relatively short lived. The refresh token can be used to renew the access token or to retrieve an access token for an alternative resource.

Authenticating an Application using Azure Active Directory

Authenticating an Application using Azure Active Directory

In my previous post I discussed in brief the use of the OAuth Authorization Code workflow and the corresponding endpoints. As a brief recap, the workflow I’ll going to walk through is the following:

– User attempts to sign into an application

– Application launches the Authorize URL in an external browser

– User is directed to a Microsoft URL where they are prompted to sign in

– User signs in

– After sign in, the User is redirected back to the application via a custom protocol

– Application receives the token containing information about the user that has signed in

In this walk through I’ll use a UWP application but the workflow works well for any platform that supports custom protocol. Before I get started I’m going to need a few things:

Authorize URL – https://login.microsoftonline.com/{tenantId}/oauth2/authorize
Tenant Id – nicksdemodir.onmicrosoft.com (this can also be specified as a guid)

Next, I’m going to register an application with Azure Active Directory (Azure AD). You can think of this registration as identifying the application that is going to connect to Azure AD. In the Azure portal, open the Active Directory management pane and select App registrations

image

At the top of the app registrations pane, click the Add button. In the Create form I’ll give the application registration a name (the name is used both in the Azure portal as well as on the sign in page when a user is signing into the application). The application type needs to be set to Native – this allows the application to exchange an Authorization Code for an Access Token without having to provide a client secret.

image

The final property is the Redirect URI, which is the URL that the browser will be directed to after the user has signed in. In this case I’m specifying a custom protocol which will be used to redirect back to the application. Once the application registration is complete I can copy the Application Id from the application pane.

image

I have all the information I need in order to authenticate a user; all I need to do is form the authorization url that will be launched in the external browser:

private async void AuthenticateClick(object sender, RoutedEventArgs e)
{
    var  authorizationUrl=
        “
https://login.microsoftonline.com/nicksdemodir.onmicrosoft.com/oauth2/authorize?” +
        “client_id=40dba662-4c53-4154-a5cf-976473306060&” +
        “response_type=id_token&” +
        “redirect_uri=sample%3A%2F%2Fcallback&” +
        “nonce=1234“;
    await Launcher.LaunchUriAsync(new Uri(authorizationUrl));
}

There are various components to the authorization url:

nicksdemodir.onmicrosoft.com – The tenant where the application is registered. Alternatively use “common” for multi-tenanted applications.

0dba662-4c53-4154-a5cf-976473306060 – This is the Application ID (also referred to as the client ID) of the application registration in Azure AD

id_token – This is the requested response, which in this case is a JWT token that represents information about the user. When using OAuth to authorize access to a resource, either specify “code” or “code id_token”.

sample://callback – This is the url that the browser will be redirected to after the sign in process has been completed.

1234 – This is a application specific nonce which can be used to ensure the returned token matches the authentication request from the application.

In order for the user to be redirected back to the UWP application the “sample” custom protocol needs to be registered to the application. For a UWP application this is done by adding the following XML to the package.appxmanifest, immediately after the closing VisualElements tag.

<Extensions>
  <uap:Extension Category=”windows.protocol”>
    <uap:Protocol Name=”sample”>
      <uap:Logo>assetsStoreLogo.png</uap:Logo>
      <uap:DisplayName>Sample</uap:DisplayName>
    </uap:Protocol>
  </uap:Extension>
</Extensions>

In the App.xaml.cs file for the application, the OnActivated method needs to be overridden. This method will be invoked when the user is switched back to the application after signing in. The args property can be interrogated in order to retrieve the id_token that has information about the authenticated user.

image

The site http://jwt.io can be used to pull apart the id_token which shows the name of the user that’s signed in. It also shows the nonce which the application can match with the nonce specified in the authentication request.

image

In this post I’ve shown how you can use Azure Active Directory to authenticate a user. Note however, this is not enough to authorize a user for access to any resources. In the next post I’ll walk through using OAuth to authorize user access to a resource.

Azure Active Directory and Google OAuth 2.0 Endpoints

Azure Active Directory and Google OAuth 2.0 Endpoints

There are a lot of arguments for and against using pre-built SDKs for doing OAuth authentication with Azure AD and Google. Having worked with the ADAL library for Azure quite a bit I think the team have done a reasonable job, especially considering it now works across the three mobile platforms (iOS, Android and Windows), and works with a PCL that is .NET Standard based. However, using any library does force you into working within the bounds of the library. For example, we recently found two shortcomings in the library:

– It doesn’t provide a good solution for doing a browser based workflow for signing in – instead it uses a webview hosted within the context of the application (depending on the platform this may be augmented with more security, for example the Web Authentication Broker – https://msdn.microsoft.com/en-us/library/windows/apps/windows.security.authentication.web.webauthenticationbroker.aspx). A browser based workflow involves launching the external browser for the user to sign in; upon successful sign on, the user is redirected back to the app.

– It doesn’t provide a mechanism to clear cached credentials. Whilst the tokens can be cleared, this doesn’t clear the cookies held within the hosted webview, which can lead to issues if the application is multi-tenanted.

If the provided libraries don’t align with what you want, you may have to roll your own solution. The Authorization Code workflow requires two endpoints:

– Authorize URL – this is the URL that you navigate the user to in order for them to sign into your application. After signing in an Authorization Code is returned to the application

– Token URL – this is the URL that the application does a POST request to in order to convert the Authorization Code into an access token.

For Azure Active Directory, these endpoints are:

Authorize – https://login.microsoftonline.com/{tenantId}/oauth2/authorize

Token – https://login.microsoftonline.com/{tenantId}/oauth2/token

For Google, these endpoints are:

Authorize – https://accounts.google.com/o/oauth2/v2/auth

Token – https://www.googleapis.com/oauth2/v4/token

As both services conform to OAuth/OpenID Connect, the parameters are the same, although there are some variations on the values that you need to supply for scope and client id.

Useful OAuth, OpenID Connect, Azure Active Directory and Google Authentication Links

Useful OAuth, OpenID Connect, Azure Active Directory and Google Authentication Links

Over the past couple of weeks I’ve been assisting with the development work of an enterprise system that uses both Azure Active Directory (Azure AD) and Google to authenticate users. It’s a cross platform solution which means we need code that works across both authentication platforms, and the three mobile platforms. Unfortunately this is easier said than done – The Azure AD team have done a reasonable job with the ADAL library but it’s not like we can repurpose that library for authenticating against Google. This is a tad annoying since both Azure AD and Google both use OAuth and OpenID Connect, so you’d expect there to be a good library that would work across both.

In trying to find a workable solution I can across a number of links that I want to bookmark here for future reference:

OAuth 2

Home – https://oauth.net/2/

The OAuth home page is a good starting point if you want to get more links and information about OAuth (1 and 2) but I actually found it’s main use for me was to point at the OAuth 2.0 Framework RFC

OAuth 2.0 Framework RFC – https://tools.ietf.org/html/rfc6749

You can think of the OAuth 2.0 Framework RFC as being the specification for OAuth 2.0. There are some extensions and other standards that relate to OAuth 2.0 but this is a must read if you want to understand what OAuth 2.0 is all about. You may need to refer back to this when reading other blogs/tutorials as it can help clarify what each of the roles and responsibilities are in the process.

Simple overview of OAuth 2 – https://aaronparecki.com/2012/07/29/2/oauth2-simplified

This overview provides a quick summary of the various flows for OAuth 2.0. However, I disagree with the use of the implicit workflow for mobile applications. Whilst mobile applications are not “trusted,” which would normally imply the use of the implicit workflow, the reality is that the implicit workflow can’t issue refresh tokens. This means that unless you want your users to have to log in each time they use your mobile application, you need to use the Authorization Code workflow (the client secret shouldn’t be required when requesting access tokens for mobile apps – this depends on which authentication provider you’re using).

 

OpenID Connect

Home – http://openid.net/connect/

The OpenID Connect home page is again a good starting point as it links to the many different parts of the OpenID Connect standard. OpenID Connect builds on top of OAuth 2.0 in order to provide a mechanism for users to be authenticated as well as authorized for resource access. In addition to the creation of access tokens, OpenID Connect defines an id_token which can be issued in absence of any resource that is just used to identify the user that has authenticated.

OpenID Connect Core 1.0 – http://openid.net/specs/openid-connect-core-1_0.html

This is the core specification of OpenID Connect. Similar to the specification for OAuth, this is worth both a read and to be used as a reference when working with OpenID Connect implementations.

OpenID Connect Session Management 1.0 – http://openid.net/specs/openid-connect-session-1_0.html

Whilst still in draft this standard covers how implementers are supposed to handle log out scenarios, which is useful as your application can’t simply delete it’s access tokens when a user opts to log out. Ideally when a user logs out, you’d want to make sure both cached tokens are cleared, along with invalidating any access or refresh tokens.

 

Google

OAuth 2.0 Overview – https://developers.google.com/identity/protocols/OAuth2

OpenID Connect – https://developers.google.com/identity/protocols/OpenIDConnect

Google’s documentation isn’t too bad but does require you to read all of the pages as the OAuth and OpenID Connect implementation details seem to be scattered across the pages. The assumption is that for any given type of application you can simply read the one page – unfortunately, if you want to get an understanding of the Google implementation, you really need to read everything. Authenticating/authorizing with Google is significantly simpler than with Azure AD as there is no notion of linking your application registration with specific permissions to other applications registered with Azure AD. This is a significant limitation of using Google sign in, as you can really only use it to authenticate and then use the token to access various Google APIs.

 

Azure Active Directory

Azure AD Developer’s Guide – https://docs.microsoft.com/en-au/azure/active-directory/develop/active-directory-developers-guide

Authentication Scenarios for Azure AD – https://docs.microsoft.com/en-au/azure/active-directory/develop/active-directory-authentication-scenarios

Azure AD is a much longer read, and it’s very easy to get lost in the world of application configuration and settings. My recommendation is to start with something simple, and then grow from that. For examples, start by authenticating a use to sign into your mobile app, then extend it so that you can use the access token to connect to a Web API, and then on to retrieve information from other Microsoft services within the Web API, and then perhaps make it all multi-tenanted (that’s one for another post!).