azure active directory

65
1 Azure Active Directory By Mohamed Waly

Upload: mohamed-a-waly

Post on 11-Sep-2015

144 views

Category:

Documents


12 download

DESCRIPTION

Learn What is Azure AD and how to use it.

TRANSCRIPT

  • 1

    Azure Active Directory

    By

    Mohamed Waly

  • 2

    Table of Contents

    About the Author......................................................................................................... 4

    Chapter 1: Introduction ............................................................................................ 5

    1.1 What Azure Active Directory is and (is not) .............................................. 5

    1.2 Users and Groups .......................................................................................... 7

    1.3 Work or Student Accounts .......................................................................... 7

    1.4 Microsoft Accounts ....................................................................................... 9

    1.5 Adding Users and Groups to Azure AD ..................................................... 9

    1.6 Custom Domains ......................................................................................... 10

    1.7 Protocols supported by Azure AD ............................................................ 11

    1.8 From Protocols to Application Endpoints ............................................... 12

    1.9 Adding Applications to Azure AD ................................................................ 14

    1.10 Summary .................................................................................................... 15

    Chapter 2: Building Web Applications for Azure AD ......................................... 16

    2.1 Introduction ................................................................................................... 16

    2.2 Add a Web Application to Azure AD using Visual Studio........................... 17

    2.3 Add a Web API Application to Azure AD using Visual Studio ................... 24

    2.4 Identity in the .NET Framework ................................................................. 32

    2.5 Summary ....................................................................................................... 34

    Chapter 3: Developing Native Client Applications ............................................. 36

    3.1 Introduction ................................................................................................... 36

    3.2 Using claims in the Web API to drive application behavior ......................... 37

    3.3 Exposing the Web API to other applications ................................................ 40

    3.4 Add a native client application to Azure Active Directory ........................... 43

    3.5 Configure permissions to access the Web API ............................................. 45

  • 3

    3.6 Develop the native client application ............................................................ 45

    3.6.1 DEFINE SETTINGS USED BY THE NATIVE CLIENT

    APPLICATION ................................................................................................ 46

    3.6.2 CALL THE WEB API TO GET VALUES .................................. 49

    3.6.3 CALL THE WEB API TO POST A NEW VALUE .................. 51

    3.6.4 RUNNING THE NATIVE CLIENT APPLICATION ....................... 52

    3.7 ADALs Token Cache and Refresh Tokens .................................................. 54

    3.8 Summary ....................................................................................................... 54

    Chapter 4: Group Claims ........................................................................................ 56

    4.1 Introduction ................................................................................................... 56

    4.2 Using Group Claims to Drive Authorization Decisions ............................... 57

    4.2.1 ENABLE GROUP CLAIMS FOR THE

    CLOUDALLOC.WEBAPI APPLICATION ............................................... 58

    4.2.2 LOCATE THE OBJECT ID FOR THE DEV/TEST

    SECURITY GROUP ...................................................................................... 59

    4.2.3 UPDATE THE POST METHOD TO LOOK FOR DEV/TEST

    GROUP CLAIM ............................................................................................... 60

    4.2.4 EXAMINING THE GROUP CLAIMS .......................................... 62

    4.3 Working with the Azure AD Group Claims Limit ........................................ 64

    4.4 Summary ....................................................................................................... 65

  • 4

    About the Author

    Mohamed Waly: I'm a former Hyper-V MVP, Microsoft Student Partner, I use to

    deliver sessions about Virtualization Technology and Cloud Computing.

  • 5

    Chapter 1: Introduction

    1.1 What Azure Active Directory is and (is not)

    Azure Active Directory (aka Azure AD) is a fully managed multi-tenant

    service from Microsoft that offers identity and access capabilities for

    applications running in Microsoft Azure and for applications running in

    an on-premises environment. Its name leads some to make incorrect

    conclusions about what Azure AD really is. Therefore, to avoid any

    confusion with Windows Server Active Directory that you may already

    be familiar with in an on-premises environment, understand that Azure

    AD is not Windows Server Active Directory running on Virtual Machines

    in Microsoft Azure.

    Azure AD is not a replacement for Windows Server Active Directory. If

    you already have an on-premises directory, it can be extended to the

    cloud using the directory integration capabilities of Azure AD. In these

    scenarios, users and groups in the on-premises directory are synced to

    Azure AD using a tool such as Azure Active Directory Sync (AAD Sync).

    This has the benefit of users being able to authenticate against

    Windows Server Active Directory when accessing on-premises

    applications and resources, and authenticating against Azure AD when

    accessing cloud applications. The user can authenticate using the same

    credentials in both scenarios.

    Azure AD can also be an organizations only directory service. For

    example, many startups today dont have an on-premises Windows

    Server Active Directory. In these scenarios, an organization may simply

    rely on Office 365 and other SaaS applications to conduct its business

    and manage its users identity and access to SaaS applications, all

    online.

    As a developer of cloud applications, you can use Azure AD to

    accomplish things such as single sign-on (SSO) for your cloud

    applications, query the directory for user and group information, and

  • 6

    even write to the directory provided your application has the

    permissions to do so. Of course, you can accomplish similar ideas on-

    premises and build applications using Microsoft proprietary

    technologies such as Windows NTLM, Kerberos, LDAP and so on.

    However, as more applications are developed with the intent of running

    in the cloud, and access to those applications cross organizational

    boundaries, and are accessed from a growing number of devices across

    a variety of platforms, organizations need an enterprise ready directory

    service that can handle the authentication needs of the organization

    and the applications it depends on. The graphic below illustrates how

    Azure Active Directory could be used in a company to address some

    common enterprise needs.

    Figure 1.1

    Throughout this book, the focus will be on the developer, with careful

    attention given to the tools, libraries and features of Azure AD that can

    be used to build cloud applications that are protected by Azure AD. This

    chapter lays the groundwork for some key concepts in Azure AD. Future

    chapters in this book will go deep into the developer experience for

    different types of cloud applications.

  • 7

    1.2 Users and Groups

    In Azure AD there are two entities that we are most concerned with

    during application development; the user and perhaps the group (or

    groups) the user is a part of. We use the users claims (statements about

    the user from Azure AD) to drive application behavior such as

    personalizing screens or making authorization decisions about what the

    user can do. By externalizing the authentication of users to Azure AD

    were able to rely on the claims provided in the authentication token for

    the user to drive these application experiences.

    A user in a directory can be sourced from either a directory in Azure AD,

    which is referred to as aWork or Student Account (previously called

    an Organizational Account). Or, the user can be sourced from a

    Microsoft Account. An example of how this may look in the Azure AD

    Users page of the Azure Management Portal is shown here.

    Figure 1.2

    1.3 Work or Student Accounts

    Users are generally added to a directory in Azure AD as a Work or

    Student Account user (formerly know as Organizational Accounts). A

    users user name and email address will take the form

    of @.onmicrosoft.com and the account

    typically exists for as long as the user is part of the organization and

    until an Administrator removes the account. If you have ever had an

    account in an on-premises Windows Server Active Directory (for

    example, at work) then this is essentially the same concept.

    A user from a different directory in Azure AD can also be added to a

    directory (aka external user). This is particularly useful in situations

    where users in different directories need access to the same cloud

  • 8

    applications protected by Azure AD. This is a very powerful scenario and

    one that is increasing popular as more and more organizations partner

    with one another. Consider, for example, a user John Doe from

    CompanyA ([email protected]) is added as a user

    to the directory for CompanyB. This would enable John Doe to access

    CompanyBs cloud applications protected by CompanyBs Azure AD.

    Now, when John Doe authenticates, he will do so in the realm of

    CompanyAs directory, not CompanyBs directory. So, his profile data,

    password, policies, etc. are all managed by the administrators at

    CompanyA. As it should be CompanyA knows him best and is the

    authority that can properly authenticate him. Given that CompanyA and

    CompanyB have established trust between the two organizations,

    CompanyB can add John Doe to their directory so he can collaborate

    with users and applications in CompanyB. If CompanyB decides later to

    remove John Doe from the directory, then he will no longer be able to

    access CompanyBs resources. However, suppose John Doe quits

    CompanyA or is removed from the organization for other reasons. What

    is the first thing IT generally does in this case? They delete John Doe

    from the directory (or at least disable the account). They probably dont

    call all their partners such as CompanyB to tell them that John Doe

    should be removed. But thats ok, because as I pointed out earlier, John

    Doe will never authenticate in the realm of CompanyBs directory. He

    will authenticate against CompanyAs directory. And since his account

    will have been either removed or disabled, he wont be able to

    successfully authenticate, and therefore wont be able to access any

    CompanyB resources even though his account technically still exists in

    CompanyBs directory. If you have been in this industry for at least a few

    short years you can probably appreciate the immense flexibility and

    level of security this brings to an organization.

    During authentication, Work or Student Account users may notice the

    blue badge icon shown above. This icon is a visual hint to the user

    signing in using a Work or Student Account.

  • 9

    1.4 Microsoft Accounts

    Users can also be added to a directory in Azure AD as a Microsoft

    Account user. In this scenario, the user name and email address will

    likely take the form of @hotmail.com,

    @outlook.com, or @live.com. A Microsoft

    Account is an individual account that a user has created to access

    consumer services such as Xbox LIVE, Messenger, Outlook/Hotmail, etc.

    Unlike the Organizational Account, these accounts dont get deleted

    when they are removed from a directory in Azure AD. The account

    belongs to the person in this case, not an organization. However, Azure

    AD enables organizations to add users to their directory using a

    persons Microsoft Account and these users are also considered external

    users of the directory.

    One scenario where you might add a user to a directory in Azure AD

    using a persons Microsoft Account is in a freelance situation where

    you need an external user (someone that is not part of the organization)

    to have access to cloud applications for a particular project or service

    agreement. This prevents the user from having to keep up with a

    separate set of user credentials just to access the necessary application

    resources for the project. When the project term ends the user can

    simply be removed from the directory.

    During authentication Microsoft Account users may notice the Windows

    icon shown above. This icon is a visual hint to the user signing in using a

    Microsoft Account.

    1.5 Adding Users and Groups to Azure AD

    Users and Groups can be added to a directory in a variety of ways. In no

    particular order here are some common methods:

    By syncing from an on-premises Windows Server Active Directory using

    AAD Sync. This is how most enterprise customers will get their users

  • 10

    added to the directory and requires some additional server

    configuration on-premises to setup.

    Manually using the Azure Management Portal. The portal experience is

    very easy and intuitive. Organizations that dont have an on-premises

    directory may use this approach for its simplicity, provided the number

    of users is relatively small. This is also very useful during development

    and test phases of application development.

    Scripted using PowerShell and the Azure Active Directory cmdlets.

    PowerShell makes automating this task very useful, particularly for large

    user bases. This too can be very useful during development and testing.

    Programmatically using the Azure AD Graph API. This is an extremely

    powerful option that essentially gives you full control of how users are

    added to the directory. We will see examples of this later in the book.

    1.6 Custom Domains

    Every directory in Azure AD gets a unique DNS name on the shared

    domain *.onmicrosoft.com. So, as an example, for a directory named

    cloudalloc, the DNS name would becloudalloc.onmicrosoft.com. A

    user in the directory would therefore have a user name such

    [email protected].

    By using a custom domain you are able to associate a domain you own

    with a directory in Azure AD. This is not required, but often preferred by

    customers who own their own domain name. Continuing with the same

    example, if you owned the cloudalloc.com domain a user name would

    take the form [email protected] instead of

    [email protected].

    Configuring a custom domain and associating it with a directory in

    Azure AD is a relatively simple process. First, you need to own the

  • 11

    domain name you want to use with your directory. Next, you need to go

    through a domain verification step in Azure AD, which basically involves

    updating the DNS records with your domain registrar to include a TXT

    record and value (provided by Azure AD) to prove you own the domain.

    The details for configuring a custom domain are covered in full detail in

    this Verify a domain article on TechNet.

    1.7 Protocols supported by Azure AD

    As a developer building applications protected by Azure AD you will

    find that Azure AD provides support for all the common protocols that

    can be used to secure your applications. Some of these protocols have

    been around for a really long time and as a result are widely used in the

    industry today. Others are still emerging as a new (and preferred) way to

    protect access to cloud applications. The protocols supported are shown

    here:

    WS-Federation This is arguably one of the most well-known and used

    protocol today for authenticating users of web applications. Microsoft

    uses this when authenticating users for some of their own cloud

    applications, such as the Microsoft Azure Management portal, Office

    365, Dynamics CRM Online, and more. There is fantastic tooling support

    in Visual Studio 2010, 2012, and 2013 for this protocol making it very

    easy for developers to protect their applications using Azure AD. The

    token format used in this protocol is SAML.

    SAML-P This is also a widely adopted protocol and follows a very

    similar authentication pattern to WS-Federation. However, it does not

    get the same level of tooling support that WS-Federation gets. The

    token format used in this protocol is also SAML.

    OAuth 2.0 This is an authorization protocol that has been quickly and

    widely adopted in the industry as a way to sign-in users using their

    credentials at popular web applications such as Facebook, Twitter, and

    other social applications. Some of the benefits of this protocol is its

    smaller token format, JSON Web Token (JWT), and application scenarios

  • 12

    it simplifies such as accessing Web APIs from a native client with an

    access token. To do the latter with WS-Federation or SAML-P involves a

    lot of intricate code and configuration.

    OpenID Connect This is a protocol that adds an authentication layer

    on top of the existing OAuth 2.0 protocol. Because it is layered on

    OAuth 2.0, it benefits from the highly efficient JWT token format that

    OAuth 2.0 uses.

    The OAuth 2.0 and OpenID Connect just recently became Generally

    Available (GA, or fully supported and out of preview in September of

    2014) on Azure AD and there is a great amount of work going into

    libraries like Active Directory Authentication Library (ADAL) and OWIN

    middleware components to light up scenarios these protocols enable for

    developers. This book will cover these libraries in great detail in later

    chapters. The type of application you build and the requirements for your

    application will largely determine which of these protocols is used to

    protect the application when registering it with Azure AD. For now, it is

    enough to know they are supported by Azure AD.

    1.8 From Protocols to Application Endpoints

    The support for these protocols is surfaced in Azure AD through a set of

    Application Endpoints. These endpoints are unique for each directory (or

    tenant) in Azure AD. The table below shows application endpoints and

    URL for each of the supported protocols. It is these endpoints that your

    application uses to leverage the various protocols when authenticating

    users. Notice that every endpoint starts

  • 13

    with https://login.windows.net//, where is a

    unique identifier for the directory.

    Application

    Endpoint

    URL

    Federation

    Metadata Document

    https://login.windows.net//federationmetadata/2007-

    06/federationmetadata.xml

    WS-Federation https://login.windows.net//wsfed

    SAML-P https://login.windows.net//saml2

    OAuth 2.0 Token https://login.windows.net//oauth2/token

    OAuth 2.0

    Authorization

    https://login.windows.net//oauth2/authorize

    In each of these endpoints, can be either the Guid that is

    assigned to the directory, or the hostname of the directory. In other

    words, for an Azure Active Directory named cloudalloc with a tenant id

    of 530c3a3b-e508-4826-997a-38fb543bc87f, the following two URLs

    for the WS-Federation endpoint would be equivalent.

    https://login.windows.net/cloudalloc.onmicrosoft.com/wsfed

    https://login.windows.net/530c3a3b-e508-4826-997a-

    38fb543bc87f/wsfed

    If a custom domain was configured for the directory, then the domain

    name could also be substituted for .

    As this book progresses we will see how these endpoints are leveraged

    for various types of applications.

  • 14

    1.9 Adding Applications to Azure AD

    Adding applications to an Azure AD tenant (or directory) is necessary

    when you want users in your organization to be authenticated against

    your directory before accessing the application. By adding the

    application to the directory (or registering it), you are adding

    configuration that Azure AD will need to identify your application as an

    application so that it can issue authentication tokens when

    authenticating users.

    Applications you develop can be registered with a directory in Azure AD

    by using tools such as Visual Studio, the Azure Management Portal and

    other command line tools. The Azure Management Portal provides an

    easy wizard experience to get the process started as shown here when

    you click on the add application button in the portal.

    Figure 1.3

    When you choose the option to add an application my organization

    is developing, you must next indicate the type of application you are

    going to add. The reason the type is important is because it is here

    where necessary protocol artifacts will be collected leading you

    eventually to the use of either WS-Federation or OAuth / OpenID

    Connect. The two choices are:

  • 15

    Web Application and/or Web API Think of browser-based web

    applications or services that are accessed using a browser and/or

    protocols of the web.

    Native Client Application Think of client applications that will run on

    a desktop computer, laptop, or other smart device.

    1.10 Summary

    In this chapter I introduced Azure AD and some important concepts

    regarding users. I talked briefly about custom domains and then wrapped

    up by covering the protocols supported by Azure AD and how they are

    surfaced through application endpoints unique to the directory. In the

    next chapter, Ill dive into the developer experience and talk about

    building on the first of the two choices mentioned in the last section

    which is Web Applications and/or Web APIs.

  • 16

    Chapter 2: Building Web Applications for Azure AD

    2.1 Introduction

    In the last chapter I introduced some basic concepts about Azure Active

    Directory and ended with a review of the protocols and application

    endpoints that are used to build applications protected by Azure AD. In

    this chapter I will continue by talking about developing Web

    Applications and Web APIs protected by Azure AD using Visual Studio

    2013.

    Before I get into the developer experience of building a Web

    Application or Web API protected by Azure AD using Visual Studio, I

    want to quickly pick up where I left off on the previous chapter and talk

    about the portal experience of adding an application to your directory.

    The experience is extremely simple and prompts you to make only four

    choices as shown below, two of which require very little thought.

    Figure 2.1

    Here is a quick description of the four prompts.

  • 17

    1. The name of your application. This can be any name you want and is

    simply how you will identify the application in your Azure Active

    Directory.

    2. The type of application. Notice that Web Applications and Web APIs

    are considered the same type of application as far as Azure AD is

    concerned. Since this article is about both, that makes this an easy

    decision.

    3. A Sign-On URL. This is the URL where users will access your application.

    There is no verification of this URL so even if the application hasnt been

    developed yet the portal will still let you add it.

    4. An App Id URI. Notice this is a URI and not a URL. This is what Azure AD

    will use to identify your application when authentication users

    requesting access to it. It can be practically anything you want as long

    as it is unique in your directory and a valid URI.

    Now, click the checkmark and you have registered an application in

    Azure AD. Is it really that simple? Well, not really. What you have is just

    enough information at your fingertips to go build the application you

    just added to your directory. And if you continue down this path I

    promise you will learn to appreciate the degree of automation that

    Visual Studio and the Azure SDK provides for you when building Web

    Applications and/or Web APIs that are protected by Azure AD.

    So, lets develop that appreciation now.

    2.2 Add a Web Application to Azure AD using Visual Studio

    To get started building a web application protected by Azure AD, you

    must navigate your way through a few new project wizard dialogs. If you

    do this correctly, you will have a new web application that is also added

    to your Azure AD and configured properly, resulting in the F5 (Run)

    experience weve become so accustomed to from Visual Studio.

  • 18

    Assuming that you are starting from the ASP.NET Project template for

    an MVC application and will be hosting it in an Azure Website, the first

    thing you must do is change the authentication type to use

    Organizational Accounts (the same as Student or Work accounts

    mentioned in the last article) and enter the domain (Azure AD tenant)

    you are externalizing authentication to. In my sample shown here, the

    Azure AD Tenant is configured with a custom domain otherwise it would

    be .onmicrosoft.com.

    Figure 2.2

    The next change you must do is specify an existing Azure SQL Database

    Server to use with your application or create a new one. The reason why

    this is required is because the code that is added to your project by the

    ASP.NET project template when using Organizational Accounts requires

    it.

  • 19

    Figure 2.3

    These are the only two changes you would have to make to successfully

    create a web application and add it to your Azure Active Directory using

    Visual Studio. If you prefer a step-by-step experience that walks you

    through every dialog and more, then please see Authenticating with

    Organizational Accounts and Azure Active Directory. And if you are

    interested in further understanding the SQL Database dependency I

    mentioned above, then see Deep Dive: Azure Websites and

    Organizational Authentication using Azure AD.

    The application produced by the ASP.NET template uses Windows

    Identity Foundation (WIF) in the .NET Framework to take care of

    authenticating users accessing the application. WIF provides the

    implementation of protocols such as WS-Federation that an application

    like this uses to authenticate users. It handles redirecting

  • 20

    unauthenticated users to the correct sign-in (and sign-out) URL for their

    realm, verifying the signature of the SAML token issued to the client

    after successfully authenticating, managing session tokens and cookies

    for the client, extracting claims about the user from the token, and

    putting these claims in the principal object of the current thread. Most

    of this functionality is implemented in two HTTP modules that WIF

    provides, which are

    the WSFederationAuthenticationModule and SessionAuthentication

    Module. Visual Studio takes care of adding these in the web.config as

    shown here.

  • 21

    Visual Studio also adds the configuration necessary to insure that

    session security tokens can be used in a web farm type of environment

    across multiple machines. This is absolutely critical in situations where

    you have an Azure Website, Cloud Service or Virtual Machine configured

    with multiple instances hosting your web application. Otherwise, users

    would have to re-authenticate every time they landed on a different

    instance or be bound to a single instance throughout the entire session

    neither of which is good for scale. This powerful feature is achieved by

    removing the default token handler that uses the Data Protection API

    (DPAPI) and replacing it with a token handler that uses a common

    machine key available to all instances as shown here. And again, this is

    taken of for you by the template. If you want to know where that key is

    and how it comes into the equation see the deep dive link I mentioned

    earlier.

  • 22

    Another important element in this section of the configuration is

    the element. This is the class that has been

    added to your project that WIF will use to validate the SAML tokens

    presented to the web application. You can find it in the Utils folder of

    your project.

    Stepping out of the WIF configuration for a moment, if you look in

    the section you will find some settings that should look

    familiar.

  • 23

    The first is the ida:FederationMetadataLocation. Recall from the first

    chapter in this book that this was the first endpoint listed that is unique

    to my Azure Active Directory. In this metadata document is a massive

    amount of information about my directory tenant in Azure AD, including

    the public key that is used to validate tokens. The ida:Realm is used

    when unauthenticated users are redirected to Azure AD to sign-in and

    the ida:AudienceUri is that unique identifier in Azure AD that I

    mentioned at the very beginning of this chapter. So, where do these

    appSetttings get used? Go look in App_Start\IdentityConfig.cs another

    class added to your project by the ASP.NET template.

    Are you starting to appreciate all the intricate WIF configuration

    necessary to make a web application secure with just a few clicks? There

    is so much more that I dont have space here to get into. So let me end

    this with just one more element in the configuration you should at least

    be aware of, which is the element as

    shown here.

  • 24

    This configuration applies specifically to the

    WSFederationAuthenticationModule that I mentioned earlier. Notice the

    issuer property which should also look familiar. Recall from the first

    chapter in this book that this was the second endpoint listed that is

    unique to my Azure Active Directory and is where users sign-in and sign-

    out of the web application.

    2.3 Add a Web API Application to Azure AD using Visual Studio

    To get started building a Web API application protected by Azure AD

    using Visual Studio, start with the same ASP.NET project template but this

    time choose Web API as shown here.

  • 25

    Figure 2.4

    The rest of the experience is the same as for web applications with one

    very important difference the Web API project has no requirement

    for a SQL Database. Now, you may want to have a SQL Database linked

    to your Web API, but just understand that the project template in this

    case does not emit any code in your project that absolutely requires it.

    So, youre free to choose the No database option if you like as shown

    here.

  • 26

    Figure 2.5

    The application produced by the ASP.NET template in this scenario

    uses Microsoft Open Web Interface for .NET (OWIN) Components to

    take care of authenticating users accessing the application. OWIN is still

    relatively new and is essentially a specification that defines a standard

    interface between .NET web servers and web applications. Microsofts

    OWIN Components (aka project Katana) provide an open source

    implementation of the OWIN specification with goals of being portable,

    modular, and lightweight.

    The application in this scenario uses OAuth 2.0 to secure the Web APIs

    (REST APIs) and therefore uses the OAuth 2.0 application endpoints in

    Azure AD that I mentioned in the first chapter of the book. The

    implementation also takes advantage of the JSON Web Token (JWT)

  • 27

    format that is much lighter than the SAML token format we saw

    previously.

    Unlike WIF, OWIN is not a core component of the .NET Framework 4.5

    stack. Instead, it is delivered to your project through a set of Nuget

    packages as shown below, consisting of the community owned and run

    Owin package (Owin.dll) and several Microsoft Owin Components that

    provide the implementation of the OWIN specification.

    The Owin package contains the IAppBuilder interface which

    standardizes the startup process for the application. Ill come back to

    this interface shortly.

    The web.config for this project is far less verbose and essentially comes

    down to just a couple of appSettings that link back to the application

    registration in Azure AD.

  • 28

    The ida:Tenant and ida:Audience have the same meaning as previously

    discussed. Theida:ClientID is a unique identifier for the application in

    Azure AD and is used if/when the Web API accesses other applications

    in Azure AD. We will see this used a lot in the next couple of chapters in

    this book. Thats basically it for the configuration!

    Lets turn attention now to the code, which essentially comes down to

    two files being added in your

    project: Startup.cs and Startup.Auth.cs as shown here.

  • 29

    Figure 2.6

    Startup.cs provides the class name and method signature that Katana

    applications look for to configure the Microsoft OWIN components. The

    Configuration method takes an IAppBuilderinterface which if you recall,

    is the interface defined in the Owin.dll.

    using Owin;

    namespace CloudAlloc.WebAPI

    {

  • 30

    public partial class Startup

    {

    public void Configuration(IAppBuilder app)

    {

    ConfigureAuth(app);

    }

    }

    }

    The Configuration method simply calls the ConfigureAuth method in

    the Startup.Auth.cs file that was added to the project that in turn adds

    the Azure Active Directory JWT Bearer Token middleware to the

    applications HTTP request pipeline as shown here. Notice that it is here

    where the two appSettings in web.config are pulled in the configuration.

    using System;

    using System.Collections.Generic;

    using System.Configuration;

    using System.Linq;

    using Microsoft.Owin.Security;

    using Microsoft.Owin.Security.ActiveDirectory;

    using Owin;

  • 31

    namespace CloudAlloc.WebAPI

    {

    public partial class Startup

    {

    public void ConfigureAuth(IAppBuilder app)

    {

    app.UseWindowsAzureActiveDirectoryBearerAuthentication(

    new WindowsAzureActiveDirectoryBearerAuthenticationOptions

    {

    Audience = ConfigurationManager.AppSettings["ida:Audience"],

    Tenant = ConfigurationManager.AppSettings["ida:Tenant"]

    });

    }

    }

    }

    The bearer token middleware simply means that any party in possession

    of a token (a bearer) can use it get access to the resource (the Web

    API endpoints in this case) as defined in the OAuth 2.0 Authorization

    Framework specification.

    Just like in the Web Application scenario, this Web API project has all of

    these details implemented for you and the application is automatically

    registered in Azure Active Directory. Unlike the Web Application

    scenario, you cannot just press F5 to run it in your browser. This is a

    Web API project that expects you to be the bearer of a JWT token to

  • 32

    access the endpoints of the application. Ill show you how to get that

    token and use it to access the Web API endpoints in the next chapter.

    2.4 Identity in the .NET Framework

    Whether authentication of users is accomplished using the WS-

    Federation or OAuth 2.0 endpoints in your Azure Active Directory, and

    whether a SAML or JWT token was presented to your application, once

    your application is invoked you can access all the claims that Azure AD

    (or the users identity provider) issued when the user was authenticated.

    This is possible because your application is claims-aware and is the case

    for any .NET application targeting .NET Framework 4.5 or newer.

    In a claims-aware application the clients identity is presented as a

    collection of claims to the application. And as you know, these claims

    are delivered via the authentication token that the client received from

    their identity provider (ie: Azure AD) after successfully authenticating.

    Aclaim is a statement about the user that the identity provider can

    corroborate. For example, my Azure AD can undeniably state that my

    email is [email protected]. A claims-aware application is one

    that relies on the claims presented to drive application behavior for the

    user because ittrusts the identity provider it has externalized

    authentication to. If you have ever heard the term relying party or RP

    to describe a claims-aware or claims-based application, that is why

    because it relies on the claims presented by the client provided the

    claims are issued by an identity provider it trusts.

    Every thread in a .NET application has a ClaimsPrincipal object that can

    be used to discover the identity of the client, the identity provider that

    authenticated the client, and the claims the identity provider included in

    the authentication token. If you are already familiar with the traditional

    IPrincipal interface in .NET, then you already know about the principal

    object on the thread. And as you can see in the diagram below, the

    ClaimsPrincipal class implements the IPrincipal interface making it

  • 33

    compatible with existing code. The ClaimsPrincipal also has a Claims

    property that you can use to access an individual Claim for a client.

    Figure 2.7

    These classes are core components of the .NET Framework starting with

    version 4.5. You dont need to download a Nuget package or install an

    SDK. These classes are as common as System.String and are defined in

    the mscorlib assembly. So, if youre targeting .NET Framework 4.5 or

    newer, then your application is a claims-aware application.

    The ClaimsPrincipal class has a static property called Current that will

    return the ClaimsPrinicipal object for the thread. It is also equipped with

    some handy methods you can used to find and retrieve the values of

    claims for a client

    The Claim class is used to describe statements about the Subject (or

    client) that the Issuer can prove. Each claim as a Type that describes the

  • 34

    statement, such as the Subjects Name, Email, PostalCode or any other

    custom claim that the issuer (or you) has added to the Claims collection.

    There are 50+ predefined ClaimTypes that are used for the more

    common claims. However, these ClaimTypes are simply URIs so you are

    free to create custom claims for any situation. For example, you may

    store a profile for a user that includes the make of the car he or she

    drives and add a claim for that to the Claims collection in

    a ClaimsAuthenticationManager implementation.

    An example of how you can retrieve the Surname claim for a Subject is

    shown here.

    var principal = ClaimsPrincipal.Current;

    var surnameClaim = principal.FindFirst(ClaimTypes.Surname);

    var surname = (surnameClaim != null) ? surnameClaim.Value : "";

    Or, if you prefer to use LINQ you could do something like this.

    var principal = ClaimsPrincipal.Current;

    var surnameClaim = principal.Claims.Where(c => c.Type ==

    ClaimTypes.Surname).FirstOrDefault();

    var surname = (surnameClaim != null) ? surnameClaim.Value : "";

    As you can see the object model is extremely simple to navigate to

    discover and retrieve values of claims.

    2.5 Summary

    In this chapter talked about the developer experience of building Web

    Applications and Web API applications that are protected by Azure AD.

    To recap each of these, a Web Application generated using Visual

    Studio 2013 is protected by WIFs implementation of the WS-Federation

    protocol which is configured via settings in web.config, code that is

    added to your project, and a SQL Database that stores cryptographic

    keys. The web application receives a SAML token from authenticated

  • 35

    users and WIF validates the token and extracts the claims about the

    client from the token.

    Web API applications generated using Visual Studio 2013 are protected

    by Microsofts OWIN middleware components using OAuth 2.0 and JWT

    token format. The OWIN components perform similar token validation

    and also extract the claims from the token.

    Finally, I wrapped up with a brief overview of the ClaimsPrincipal and

    Claim classes and demonstrated how you can retrieve the claims to

    drive behaviors in your application code.

    In the next chapter, I will cover the Active Directory Authentication

    Library (ADAL) and show you how you can use it to call Web APIs

    protected by Azure AD and build native client (non-browser based)

    applications for Azure AD.

  • 36

    Chapter 3: Developing Native Client Applications

    3.1 Introduction

    In the last chapter I discussed developing two types of applications

    protected by Azure Active Directory: web applications and web APIs. In

    that chapter I approached these applications from the perspective of a

    developer using Visual Studio 2013 and the project templates provided

    for creating these types of applications. The automation delivered by

    Visual Studio and the Azure SDK when creating these applications

    resulted in the two applications being registered in my Azure Active

    Directory as shown in the following Figure:

    Figure 3.1

    Testing the CloudAlloc.Website was a matter of simply pressing F5 in

    Visual Studio to launch a browser and access the application. Recall this

    application is protected using WS-Federation which redirects

    unauthenticated users to a sign-in page. After successfully

    authenticating, the user is redirected back to the CloudAlloc.Website

    URL.

    The CloudAlloc.WebAPI is protected using OAuth 2.0 and expects a valid

    token in the authorization header when its endpoint is accessed. In this

    chapter I am going to continue where I left off with the Web API

  • 37

    application and discuss how you can develop a native client to acquire

    an access token that can be used to access the Web API.

    A native client application is one that is installed on a users computer or

    device. Examples of such an application include, but is not limited to,

    WinForms, WPF, Windows Store, Windows Phone, and iOS applications.

    And while these applications may not necessarily run in Azure as

    compared to the web application and web API applications discussed in

    the previous chapter, native client applications can be protected by

    Azure Active Directory and access other applications registered with

    Azure Active Directory.

    3.2 Using claims in the Web API to drive application behavior

    Before getting into the development of a native client, I want to first

    point out two changes I made to the Web API to facilitate the topics

    discussed in this chapter.

    1. For the Get method, I changed the default implementation provided by

    the Visual Studio project template to extract the claims from the

    authenticated user and look for a scope claim with a value

    of Read_CloudAlloc_WebAPI or Read_Write_CloudAlloc_WebAPI. If

    the scope claim is found and contains one of these values, then I return

    HTTP 200 (OK). Otherwise, I return an HTTP 401 (Unauthorized).

    You may be wondering where I got the scope claim and value. Azure

    Active Directory will add this claim and value to the claim set for

    authenticated users provided that my Web API has been configured to

    support this claim and my client (native client) has been granted the

    permissions to include the claim. Ill come back to this shortly. For now,

    just understand that with this code, the Web API now requires that this

    claim and value be present for the user to be able to read these

    values.The updated Get method implementation is shown here.

    // GET api/values

    public HttpResponseMessage Get()

  • 38

    {

    // Look for the scope claim containing the

    // value 'Read_CloudAlloc_WebAPI' or 'Read_Write_CloudAlloc_WebAPI'

    var principal = ClaimsPrincipal.Current;

    Claim readValuesClaim = principal.Claims.FirstOrDefault(

    c => c.Type == "http://schemas.microsoft.com/identity/claims/scope" &&

    (c.Value.Contains("Read_CloudAlloc_WebAPI") ||

    (c.Value.Contains("Read_Write_CloudAlloc_WebAPI"))));

    if (null != readValuesClaim)

    {

    //

    // Code to retrieve values to include in the response goes here.

    //

    return Request.CreateResponse(HttpStatusCode.OK); }

    else

    {

    return Request.CreateErrorResponse(

    HttpStatusCode.Unauthorized, "You don't have permissions to read values.");

    }

    }

    2. For the chapter method, I made similar changes but instead look

    for the scope claim containing the

    value Read_Write_CloudAlloc_WebAPI. If the scope claim is

    found and contains this value, then I return HTTP 201 (Created) to

    simulate the value being added to the server. Otherwise, I return

    an HTTP 401 (Unauthorized). The updated chapter method

    implementation is shown here.

    // POST api/values

  • 39

    public HttpResponseMessage Post([FromBody]string value)

    {

    // Look for the scope claim containing the value 'Read_Write_CloudAlloc_WebAPI'

    var principal = ClaimsPrincipal.Current;

    Claim writeValuesClaim = principal.Claims.FirstOrDefault(

    c => c.Type == "http://schemas.microsoft.com/identity/claims/scope" &&

    c.Value.Contains("Read_Write_CloudAlloc_WebAPI"));

    if (null != writeValuesClaim)

    {

    //

    // Code to add the resource goes here.

    //

    return Request.CreateResponse(HttpStatusCode.Created);

    }

    else

    {

    return Request.CreateErrorResponse(

    HttpStatusCode.Unauthorized, "You don't have permissions to write values.");

    }

    }

  • 40

    Note: Generally it is recommended to organize code that tests for the

    presence of claims with this level of granularity into a

    custom AuthorizeAttribute class. By doing so you isolate the

    authorization code into one place, reducing the potential for error and

    improving maintainability of the code. However, in the interest of keeping

    the focus in this section on how claims can be used to make authorization

    decisions, Im including it directly in the method for readability.

    3.3 Exposing the Web API to other applications

    To make the Web API accessible to other applications in Azure Active

    Directory, permissions must be defined for the Web API that can be

    assigned to other applications. The Azure Management portal does not

    provide a user interface to do this. However, it does offer you access to

    the applications manifest where you can configure settings for an

    application, including settings that the portal doesnt provide a user

    interface for. Here are the steps to get to an applications manifest using

    the Azure Management portal.

    1. Go to the APPLICATIONS page for the Azure Active Directory the

    application is registered in.

    2. Click on the name of the application whose manifest youre interested

    in. For this chapter, it is the CloudAlloc.WebAPI application.

    3. At the bottom of the screen click on the MANAGE MANIFEST button

    and select the option to Download Manifest and save it to your local

    computer, as shown in the following Figure.

    Figure 3.2

  • 41

    The manifest is a JSON formatted file that contains the Azure Active

    Directory configuration for an application registered in Azure Active

    Directory. If you scroll through the file you will see the settings you see

    on the CONFIGURE page for an application and much more. The

    configuration setting were interested in for this chapter is the

    oauth2Permissions setting. By default, this is an empty array, as shown in

    the following Figure.

    Figure 3.3

    For this application (the CloudAlloc.WebAPI), I am adding two

    permissions to this array; one that allows read access to the API and one

    that allows read/write access to the API. Notice the valuethat I indicated

    for each permission. This is where the values Im looking for in the scope

    claim originate from in the Get and chapter methods above.

    "oauth2Permissions": [

    {

    "adminConsentDescription": "Allow read access to the CloudAlloc WebAPI on behalf of

    the signed-in user",

    "adminConsentDisplayName": "Read access to CloudAlloc WebAPI",

    "id": "1835E3A9-C857-4F33-A357-751E620E558D",

    "isEnabled": true,

  • 42

    "origin": "Application",

    "type": "User",

    "userConsentDescription": "Allow read access to the CloudAlloc WebAPI on your

    behalf",

    "userConsentDisplayName": "Read access to CloudAlloc WebAPI",

    "value": "Read_CloudAlloc_WebAPI"

    },

    {

    "adminConsentDescription": "Allow read-write access to the CloudAlloc WebAPI on

    behalf of the signed-in user",

    "adminConsentDisplayName": "Read-Write access to CloudAlloc WebAPI",

    "id": "87A81936-E765-4678-B6DB-8E12197AAA7D",

    "isEnabled": true,

    "origin": "Application",

    "type": "User",

    "userConsentDescription": "Allow read-write access to the CloudAlloc WebAPI on your

    behalf",

    "userConsentDisplayName": "Read-Write access to CloudAlloc WebAPI",

    "value": "Read_Write_CloudAlloc_WebAPI"

    }],

    The schema for the oauth2Permissions can be found in the MSDN

    documentation for adding, updating, and removing an application in

    Azure Active Directory.

  • 43

    After making this update to the manifest file all that is left is to upload it

    to Azure by clicking theMANAGE MANIFEST button and selecting

    the Upload Manifest option.

    Now the Web API application can be accessed from other applications

    using these permissions.

    3.4 Add a native client application to Azure Active Directory

    Regardless of the type of native client application you plan to build, the

    first step is to register it in Azure Active Directory. This is easily done using

    the Azure Management portal by clicking theADD button in

    the APPLICATIONS page of the directory and selecting the option to add

    an application my organization is developing. This will open a wizard

    where you can specify the name and type of application as Ive done in

    the following Figure:

    Figure 3.4

  • 44

    The next page of the wizard will prompt you for the redirect URI

    associated with the native client application. This is a URI (not a URL), so

    any value will work as long as it is a valid URI and is unique to your

    directory. The following Figure shows the URI for the native client

    application Im building.

    Figure 3.5

    That is all that is required to register the application with Azure Active

    Directory. The application will appear in the APPLICATIONS page of the

    directory as a Native client application as shown in the following Figure:

    Figure 3.6

  • 45

    3.5 Configure permissions to access the Web API

    Since this native client application is going to be accessing the

    CloudAlloc.WebAPI I need to configure the permissions for it. In

    the CONFIGURE page of the native client application is where

    permissions to other applications can be set. And since my Web API

    application is now accessible as a result of the manifest changes I made

    earlier, I can easily configure the native client with the permissions I want

    to give it. For now, Im going to start by assigning the Read access to

    CloudAlloc WebAPI permission as shown:

    Figure 3.7

    As users of the native client application authenticate to Azure Active

    Directory, they will now get the scope claim with a value

    of Read_CloudAlloc_WebAPI in addition to other claims issued by Azure

    Active Directory.

    3.6 Develop the native client application

    For this chapter Im going to build a simple console application for the

    native client. However, the code in this application would work the same

    for other types.

  • 46

    Recall that my Web API is protected by Azure AD and expects a security

    token when accessed from client applications. So, I need a way to

    authenticate users and acquire a security token (JWT) that can be used

    when calling the API. Thankfully, Microsoft provides a super-handy

    library called the Active Directory Authentication Library (ADAL) that

    simplifies this. Since my client application is a C# console application, Ill

    be using ADAL for .NET (version 2.x). But, there are other flavors

    available such as ADAL for JavaScript, ADAL for Node.js, ADAL for

    Java, ADAL for Android, andADAL for iOS and OSX making native client

    application development for Azure AD a breeze for the most popular

    languages and platforms used in the enterprise.

    To facilitate constructing the HTTP requests to my Web API, I will use

    the Microsoft HTTP Client Libraries (version 2.x).

    3.6.1 DEFINE SETTINGS USED BY THE NATIVE CLIENT

    APPLICATION

    The native client application needs the Client ID and Redirect URI of the

    application registered with Azure AD. The Client ID is generated

    automatically when the application is registered and the Redirect URI is

    the URI entered in the new application wizard earlier.

    // Native client application settings

    private string clientID = "386985f0-b940-4713-a8e5-f7a49d39f368";

    private Uri redirectUri = new Uri("http://cloudalloc.webapi.client");

    Both of these settings can be found in the properties section of

    the CONFIGURE page for the native client application in the Azure

    Management portal as shown:

  • 47

    Figure 3.8

    When a native client needs to get a token from Azure Active Directory, it

    needs to specify the resource it wants a token for. In this scenario the

    client application wants access to the Web API so the APP ID URI for the

    Web API is used as the resource name. After it has the token it also needs

    to know the URL where the resource can be accessed, in this case the

    address of the Web API.

    // Resource settings this application wants to access

    private string resource = "https://cloudalloc.com/CloudAlloc.WebAPI";

    private Uri WebAPIUri = new Uri("https://localhost:44313

  • 48

    Both of these settings can be found in the single sign-on section of

    the CONFIGURE page for theWeb API application in the Azure

    Management portal as shown:

    Figure 3.9

    Note: The reason the reply URL is a localhost address is simply because

    in the previous chapter when these applications were created and

    registered in Azure Active Directory, I didnt publish them to Azure

    Websites. If I had, then this reply URL would have a *.azurewebsites.net

    address instead. To see how publishing a web application and/or web API

    to Azure applies to applications registered in Azure Active Directory.

    For ADAL to authenticate the user and acquire a token for the resource,

    an AuthenticationContextmust first be instantiated by passing in the

    URL of your tenant in Azure Active Directory. The URL is of the form

    https://login.windows.net/ where can be either

    the GUID assigned to your tenant in Azure AD or the domain if you have

    a custom domain configured.

    // Session to Azure AD

    private const string authority = "https://login.windows.net/cloudalloc.com";

  • 49

    private AuthenticationContext authContext = new AuthenticationContext(authority);

    The AuthenticationContext is like a connection to your Azure Active

    Directory and is ultimately used to acquire tokens from your directory.

    3.6.2 CALL THE WEB API TO GET VALUES

    The code to issue an HTTP GET request to the Web API essentially

    breaks down to three tasks:

    1. Authenticate the user and get a token from Azure Active Directory. Here

    is where theAuthenticationContext instance is used to call

    the AcquireToken method. If the user is not already authenticated, then

    the ADAL library will launch a sign-in page for the user to sign-in with.

    After successfully authenticating, a security token to access

    the resourceusing the native client application is issued.

    2. An HttpClient instance is instantiated and configured to include

    the security token in the Authorization header for HTTP calls to the

    resource (Web API).

    3. An HTTP GET is issued to the resources URL to retrieve the values.

    The full source code for the native client to call the Get method on the

    Web API is shown here.

    public async Task ReadValues()

    {

    // Authenticate the user and get a token from Azure AD

  • 50

    AuthenticationResult authResult = authContext.AcquireToken(resource, clientID,

    redirectUri);

    // Create an HTTP client and add the token to the Authorization header

    HttpClient httpClient = new HttpClient();

    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(

    authResult.AccessTokenType, authResult.AccessToken);

    // Call the Web API to get the values

    Uri requestURI = new Uri(WebAPIUri, "api/values");

    Console.WriteLine("Reading values from '{0}'.", requestURI);

    HttpResponseMessage httpResponse = await httpClient.GetAsync(requestURI);

    Console.WriteLine("HTTP Status Code: '{0}'", httpResponse.StatusCode.ToString());

    if (httpResponse.IsSuccessStatusCode)

    {

    //

    // Code to do something with the data returned goes here.

  • 51

    //

    }

    return (httpResponse.IsSuccessStatusCode);

    }

    3.6.3 CALL THE WEB API TO POST A NEW VALUE

    The code to issue an HTTP POST request to the Web API is almost

    identical. Since this method expects a new value in the body of the

    POST, the content-type header needs to be set and the content needs

    to be passed along in the body. Otherwise, its the same code.

    The full source code for the native client to call the Post method on the

    Web API is shown here.

    public async Task WriteValue(string value)

    {

    // Authenticate the user and get a token from Azure AD

    AuthenticationResult authResult = authContext.AcquireToken(resource, clientID,

    redirectUri);

    // Create an HTTP client and add the token to the Authorization header

    HttpClient httpClient = new HttpClient();

    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(

  • 52

    authResult.AccessTokenType, authResult.AccessToken);

    // Construct the payload for the HTTP post operation

    var newValue = new StringContent(value);

    newValue.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-

    form-urlencoded");

    // Call the Web API to post the new values

    Uri requestURI = new Uri(WebAPIUri, "api/values");

    Console.WriteLine("Writing value '{0}' to '{1}'.", value, requestURI);

    HttpResponseMessage httpResponse = await httpClient.PostAsync(requestURI,

    newValue);

    Console.WriteLine("HTTP Status Code: '{0}'", httpResponse.StatusCode.ToString());

    return (httpResponse.IsSuccessStatusCode);

    }

    3.6.4 RUNNING THE NATIVE CLIENT APPLICATION

    My primitive console application calls the ReadValues method and then

    the WriteValue method shown above. When AcquireToken is called in

  • 53

    the ReadValues method, I am immediately prompted to sign-in since a

    token doesnt already exist for me.

    After successfully authenticating, a token is issued to me and the values

    are returned from the Getmethod of the Web API because the security

    token included the scope claim with

    theRead_CloudAlloc_WebAPI value.

    Next, the WriteValue method is called. This time I am not prompted to

    sign-in because ADAL has cached my token and can use it since it hasnt

    expired (more on this shortly). However, because

    the Read_Write_CloudAlloc_WebAPI value is not present in the scope

    claim, the Post method in the Web API returned an HTTP 401

    (Unauthorized).

    The full output of the console application is shown:

    Figure 3.10

    Using the Azure Management portal, I can change the permissions for

    my native client application to grant the read/write permission instead,

    as shown:

    Figure 3.11

  • 54

    Running the native client application now results in a successful call to

    both the Get and Post methods as shown:

    Figure 3.12

    3.7 ADALs Token Cache and Refresh Tokens

    Previously I mentioned that ADAL cached my token. ADAL does this

    automatically without you having to write any code, resulting in a

    positive experience for the end-user. If the token hasnt expired, ADAL

    will re-use it in subsequent calls to AcquireToken. However, even if the

    token has expired, the end-user may still avoid being prompted to sign-

    in if a refresh token was issued when the access token was issued.

    A refresh token, which may not always be present, can be used to

    acquire a new access token on behalf of the user if Azure AD allows it.

    As long as the users account in Azure AD hasnt been deleted, disabled,

    or some other change in the directory that would invalidate the token,

    the refresh token can be exchanged for a new access token. Best of all,

    ADAL will use the refresh token to acquire a new access token if it can

    and do so without you having to write any code.

    3.8 Summary

    In this chapter I demonstrated how to use claims in a Web API

    application protected by Azure Active Directory to make authorization

    decisions based on the presence of a scope claim in the authenticated

    users claim set.

  • 55

    Next, I discussed how to expose the Web API to other applications in

    Azure AD by defining permissions in the oauth2Permissions array that

    can be updated in the manifest file for the Web API. By defining

    permissions for the Web API, other applications can be configured to

    access the application with selected permissions using the Azure

    Management portal.

    After the Web API was updated and configured, I discussed the steps

    necessary to register a native client application in Azure Active

    Directory. Using values in Azure Active Directory for the registered

    native client application, I then showed how to develop a console

    application that uses the Active Directory Authentication Library (ADAL)

    and the Microsoft HTTP Client Library to securely call the Web API.

    Running the native client, we were able to observe the benefit of the

    token cache provided by ADAL and the use of a refresh token to avoid

    unnecessarily prompting the user for credentials.

    In the next chapter, I will show how you can extend this scenario and

    make authorizations decisions based on a users group membership.

  • 56

    Chapter 4: Group Claims

    4.1 Introduction

    In the last chapter I showed how you can use the Active Directory

    Authentication Library (ADAL) to build a native client application that calls

    the CloudAlloc.WebAPI introduced in earlier chapters of this book. As part

    of that chapter, I demonstrated how the Web API could be exposed to

    other applications using ouath2Permissions that I defined in the

    manifest which enabled me to assign these permissions to my native

    client application as shown:

    Figure 4.1

    Being able to assign read and write permissions in this way provided an

    easy and useful way to control an applications ability to invoke various

    operations using the claims that were issued by Azure Active Directory

    for an authenticated user. However, the level of granularity for which

    authorization decisions can be made in the application code is pretty

    coarse with this approach. In my example, it was the simple read and write

    permissions I defined and if the native client application was configured

    to allow write permissions, then any authenticated user would be able to

    invoke such operations. While that may be sufficient for some

    applications, others may require additional information about

    the user before making such authorization decisions. For example, you

    may want to restrict write operations to users in a specific security group.

    As you can see in Figure 2, the claims provided by Azure Active Directory

    for our authenticated user John Doe just dont provide that level of detail

  • 57

    about the user (yet). Other than some various identifier claims about John

    Doe, were currently limited to the values in the scope claim to make

    authorization decisions.

    Figure 4.2

    A common need for many applications is the ability to make authorization

    decisions based on a users membership in a specific security group (or

    groups). In this chapter Im going to show how you can take advantage

    of some recently released features of Azure Active Directory to do just

    that.

    4.2 Using Group Claims to Drive Authorization Decisions

    Now, you can just look for it in the Claims collection for the authenticated

    user provided you enable the group claims feature for your application in

    Azure AD. Lets see how this would work for the application weve been

    talking about and only allow users to invoke the POST method if they are

    in the Dev/Test security group.

  • 58

    4.2.1 ENABLE GROUP CLAIMS FOR THE

    CLOUDALLOC.WEBAPI APPLICATION

    Enabling the group claims feature currently requires that you update the

    manifest for the application in Azure AD. This is exactly the same

    process I showed you in the last chapter where I set

    the oauth2Permissions for the application.

    In the Azure Management portal Ill begin by going to

    the CONFIGURE page for the CloudAlloc.WebAPI application in Azure

    AD. At the bottom of the page is a MANAGE MANIFESTbutton where I

    can select to download the manifest for the CloudAlloc.WebAPI

    application as shown in Figure 3.

    Figure 4.3

    The application manifest is just a JSON file that you can edit with the

    simplest of editors (ie: notepad.exe). By the way, if youre curious what

    the GUID in the filename is about when you download the manifest, it is

    the Client ID that was assigned to the application when it was registered

    in Azure AD. Scrolling down the manifest file I will find

    the groupMembershipClaimsproperty which will be set to null as shown

    here in Figure 4.

    Figure 4.4

    Im going to change this value to SecurityGroup and then save the

    changes as shown in Figure 5.

  • 59

    Figure 4.5

    Your choices for setting the groupMembershipClaims property

    are null (the default), All orSecurityGroup. If you

    choose SecurityGroup you will get group claims in the JWT token for

    just security groups the user is a member of. If you choose All you will

    get group claims in the JWT token for security groups and distribution

    lists the user is a member of.

    All that remains now is to upload the modified manifest file which I did

    using the MANAGE MANIFEST button.

    With that change in place, I will now start getting group claims in the

    token for users of my application. As mentioned above, Im interested in

    checking for the users existence in the Dev/Test security group. So,

    before I show you the code changes needed to do this, lets review my

    security groups and where our John Doe user lands in these groups.

    4.2.2 LOCATE THE OBJECT ID FOR THE DEV/TEST

    SECURITY GROUP

    When Azure AD adds applicable group claims to the token it issues for

    my users, the value for the group claim will be the Object ID of the security

    group and not the name of the security group. Remember, every entity in

    Azure AD has a unique Object ID associated with it. You may think it

    would be more intuitive to refer to the group by name instead of the

    Object ID. This is true. However, a groups name can be changed in the

    directory so it is not a reliable identifier for the group. The Object ID will

    never change as long as the group exists. So, in this case, I need to find

    the Object ID for the Dev/Test security group. This can be found in

  • 60

    the CONFIGURE page of for my Dev/Test security group as shown here

    in Figure 6.

    Figure 4.6

    Now that I have the Object ID for the Dev/Test security group I am ready

    to make the necessary code changes.

    4.2.3 UPDATE THE POST METHOD TO LOOK FOR DEV/TEST

    GROUP CLAIM

    The only code change needed is to look for a groups claim with the value

    of 244728b5-8b9e-4e2f-8703-9853366cd431 in the authenticated

    users claims collection as shown here.

  • 61

    // POST api/values

    public HttpResponseMessage Post([FromBody]string value)

    {

    // Look for the scope claim containing the value 'Read_Write_CloudAlloc_WebAPI'

    var principal = ClaimsPrincipal.Current;

    Claim writeValuesClaim = principal.Claims.FirstOrDefault(

    c => c.Type == "http://schemas.microsoft.com/identity/claims/scope" &&

    c.Value.Contains("Read_Write_CloudAlloc_WebAPI"));

    // Look for the groups claim for the 'Dev/Test' group.

    const string devTestGroup = "244728b5-8b9e-4e2f-8703-9853366cd431";

    Claim groupDevTestClaim = principal.Claims.FirstOrDefault(

    c => c.Type == "groups" &&

    c.Value.Equals(devTestGroup, StringComparison.CurrentCultureIgnoreCase));

    // If the app has write permissions and the user is in the Dev/Test group...

    if ((null != writeValuesClaim) && (null != groupDevTestClaim))

    {

    //

    // Code to add the resource goes here.

    //

    return Request.CreateResponse(HttpStatusCode.Created);

    }

  • 62

    else

    {

    return Request.CreateErrorResponse(

    HttpStatusCode.Unauthorized, "You don't have permissions to write values.");

    }

    }

    Note: As I pointed out in the last chapter, it is a good idea to organize

    code like this into a customAuthorizeAttribute class or some other

    common class so that your application logic and authorization logic are

    not mixed together. Im intentionally leaving that as an exercise to you

    the reader though.

    Thats all there is to it! Now, lets observe the results of these changes

    by examining the claims collection for the authenticated user

    4.2.4 EXAMINING THE GROUP CLAIMS

    I ran the application under the debugger and set a breakpoint in the POST

    method so I could show you the new group claims in the claims collection.

    As shown here in Figure 7, you can see there are two groups claims

    present.

    Figure 4.7

  • 63

    The value for the first groups claim should look familiar it is the Object

    ID for the Dev/Test group I discussed earlier. The second one happens to

    be a Developer security group in my directory for which John Doe is a

    member. Figure 8 shows the membership for both security groups.

    Figure 4.8

    Notice that John Doe is explicitly identified as a member of the

    Developer security group but not the Dev/Test group. Yet, in the token

    issued to John Doe, a group claim was present for both of these security

    groups. This is because the group claims feature in Azure AD is

    transitive. So, since John Doe is a member of the Developer group and

    the Developer group is a member of the Dev/Test group, John Doe is a

    member of both security groups.

    As you can imagine, in a real world production environment a user is

    likely to be a member of many different security groups. When you

    enable the group claims feature the tokens issued for users will contain

    the group claims for all of these groups which could greatly increase the

  • 64

    size of the token. Therefore, there are limits on the number of group

    claims that Azure AD will place in a token as follows:

    JWT Tokens: Up to 200 group claims

    SAML Tokens: Up to 150 group claims

    Currently there is not a way to filter the group claims that Azure AD

    places in a token. So, if users in your directory could potentially exceed

    these limits you will need a different solution.

    4.3 Working with the Azure AD Group Claims Limit

    The Azure AD Graph API is a REST API that Azure Active Directory makes

    available for each tenant. With it you can programmatically access the

    directory and query about users, groups, contacts, tenant details and

    more. In addition to querying the directory, the Azure AD Graph API can

    be used to create, update and even delete entities in the directory.

    For the scenario mentioned above, the Azure AD Graph API could be

    used to look up the security groups a user belongs to or to check if a

    user is in a specific security group. The latter is particularly applicable in

    our scenario here and could be achieved using the IsMemberOf

    function. To execute this query you need only the Object ID of the user

    and the Object ID of the security group. The query will execute in Azure

    AD (server side) and simply return true or false. Prior to the release of

    the group claims feature in Azure AD discussed in this chapter, this was

    the only way to check group membership for a user. In situations where

    the number of groups a user is in could potentially exceed the limits

    above, it is still available to you.

  • 65

    4.4 Summary

    In this chapter, I showed how to take advantage of the new Azure Active

    Directory group claims feature and apply it to our scenario to determine

    a users membership in a particular security group. I also discussed the

    group claims limit as it applies to JWT and SAML tokens issued by Azure

    AD and how you can fall back on the Azure AD Graph

    APIs IsMemberOf function to query the directory and determine the

    same.