Steve Spencer's Blog

Blogging on Azure Stuff

Using the Azure Graph API Beta to add an Application Role Assignment

In an earlier post I talked about using Graph API to invite users using B2B and add them to groups. In this post I am introducing the Beta version of the API. This has additional functionality that is currently not released. Microsoft have provided documentation for the Graph API which currently defaults to V1.0. See https://docs.microsoft.com/en-us/graph/api/overview

To see the Beta documentation there is a version drop down list which allows you to select either V1.0 or the Beta version.

clip_image002

Just like the release version of Graph API you install the C# Graph API Beta using a nuget package: Microsoft.Graph.Beta

The code samples in here will work in both the Beta and released version but I wanted to show the difference between using the Beta API but also show you something you can use in production.

The scenario I am going to show is Adding a user to an Azure AD application.

First you will need a client to access the Beta Graph API. With the Beta API nuget package installed this automatically uses the Beta client.

ConfidentialClientApplicationOptions _applicationOptions = new ConfidentialClientApplicationOptions

{

        ClientId = ConfigurationManager.AppSettings["ClientId"],

        TenantId = ConfigurationManager.AppSettings["TenantId"],

        ClientSecret = ConfigurationManager.AppSettings["AppSecret"]

};

var confidentialClientApp = ConfidentialClientApplicationBuilder

                                                .CreateWithApplicationOptions(_applicationOptions)

                                                .Build();

ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApp);

GraphServiceClient betaGraphClient = new GraphServiceClient(authProvider);

This creates a Beta graph client with application scope.

To add an application role assignment to a user we need access to the Service Principles endpoint. Looking at the API documentation for List Service Principles we need an Application permission of Directory.ReadAll,

clip_image004

Create and Update Service Principles requires Directory.ReadWriteAll

clip_image006

We can to add the permission to the Graph API application of Directory.ReadWriteAll and Grant Admin consent to the permissions we set up in the previous post. This will also cover the List API call.

clip_image008

Without these permissions adding any calls to the Service Principle endpoint would return unauthorised.

In order to add an application role assignment we need to first obtain the user:

var user = (await betaGraphClient.Users.Request(options)                                                         

                            .Filter($"mail eq '{testUserEmail}'")

                           .GetAsync()).FirstOrDefault();

Then find all the app role assignments for the application we are interested in to see if the user is already assigned. To get the role assignments we call the service principle endpoint and expand the approleassignedto property:

var app1ServicePrincipals = await betaGraphClient.ServicePrincipals

                                                                .Request()

                                                                .Filter($"appId eq '{testApp1}'")

                                                                .Expand("approleassignedto")

                                                                .GetAsync();

var app1RoleAssignment = (from ra in app1ServicePrincipals[0].AppRoleAssignedTo

                                             where ra.PrincipalId.ToString() == user.Id

                                             select ra).FirstOrDefault();

If we want to remove the role assignment then we call the DeleteAsync method.

if (app1RoleAssignment != null)

{

        await betaGraphClient.ServicePrincipals[app1ServicePrincipals[0].Id]

                                               .AppRoleAssignedTo[app1RoleAssignment.Id]

                                               .Request()

                                               .DeleteAsync();

}

To Add a role assignment to the application call the Add endpoint:

app1RoleAssignment = new AppRoleAssignment

                                      {

                                           CreationTimestamp = DateTimeOffset.Now,

                                           PrincipalDisplayName = user.DisplayName,

                                           PrincipalId = Guid.Parse(user.Id),

                                           PrincipalType = user.UserType,

                                           ResourceDisplayName = app1ServicePrincipals[0].DisplayName,

                                           ResourceId = Guid.Parse(app1ServicePrincipals[0].Id),

                                           AppRoleId = Guid.Empty

                                      };

await betaGraphClient.ServicePrincipals[app1ServicePrincipals[0].Id]

                                                                 .AppRoleAssignments

                                                                .Request()

                                                                .AddAsync(app1RoleAssignment);

To see the role assignments that the user now has find all the appRoleAssignments that contain the users id:

var roleAssignments = servicePrincipals.SelectMany(x => x.AppRoleAssignedTo).ToList();

var appRoleAssignments = from ra in roleAssignments

                                            where ra.PrincipalId.ToString() == user.Id

                                            select ra;

foreach (var ra in appRoleAssignments)

{

        Console.WriteLine($"[{ra.PrincipalDisplayName}] [{ra.ResourceDisplayName}]");

}

This should show the same information you can see when you look in Azure AD at the User’s applications:

clip_image010

Features and tools may change between Beta and Production. The code above changed slightly when moving to productions but the easiest way to see is to remove the Beta nuget and add the production one. The only change I had to make was to change the CreationTimeStamp to CreatedDateTime = DateTime.Now.

Information about which features are in Beta and which are in production can be found here: https://docs.microsoft.com/en-us/graph/whats-new-overview

+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jkczuurVu35t/gv3L16tXPPvtMeThdFXo7adIkbC5ZVkCiQ65DUMx1XZAAEZv37t0ryy9JR0enS5cuBgYGspxt/vz5DRo0wJzRmUKJlOfOnTt58qQs5AZr9+mnnyIMy3LeDh06NGvWLFl4DcnJyV999RUWms+t+LAdPD09Hz58KMsK+PghvWPCvPbIjBkz/Pz8ZJmIiEoO5nAiIio91O4EBpaWlnJIAXmmYcOGihOHc6d6OjFiIdIaalRvvW5ubu7i4qL2wDNk3aVLl6qeGl0cTJ06NSgoSBZyQJ99fX1lQeHatWtz5szJJyuKQ8qy8PJatmz5ySefyIIKLPGHH36oVatW7969z58//8rHnHMSO8vNza1FixaySgE7dM2aNfkfh4+MjFy1apXqrn81yNL4bCxevFiWFaytrdGr1q1bq/4w4ePjs2HDhufPn8uyYh+pffzUXL16NdffWYiIqJhjDiciotLjyZMncihb5cqV5dDLu379+ty5c5UpCJFpxowZV65cOXTo0NGjR//8888ePXqIUbB+/frTp09jwMnJCQEeTp06JUYJ9vb2CLpiFKBZwVvKES8JObNZs2a7du26f//+4cOHu3btKkdkCw4OVq5dWloaoumlS5dEUWjbti0mj4qKCg0NnT59+ms+a11PTw8z+fzzz2U5B19fX3QYDR48eCBqMMmKFSuwEZ4+fTps2DBRKWBfiO0DaKN6Uzf0EwuKiIi4desWdtbBgwcDAwOxCg4ODrKF4ur0c+fOyUJuEHFzPa6OT9SBAwew0MePH3fs2FHWKmzatEn0B6ZMmSIq8alQDeHo29q1a7Gd0asTJ05grGqvvL29sevFcEJCws8//6x2538PDw9MiO1z/vz58ePH5zy/gIiISgTmcCIiolwgSu3fv181l/br1w/JR19fXxRr1qw5cuRIZRBCoEXYw1SiWBy0a9du586d7u7uNWrU6NChw+rVq7t06SLHKSCop6amiuE7d+4gmophoUePHtu2bcPkpqamDRo0QLDcvn179erV5ehXghT6008/LV26NJ9Ij5jas2fPCxcuyPJLqlOnDqadOnVq7dq1NTX/93cOVmH48OGyoHDlyhU5lDfs8Xv37mVmZj579gxpv0KFCnJEwaSlpf3666+qB94xw4EDByqf1oZeqf4wgfAfEhIihsPCwhD4xbCA/mMnurm5Va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Tq1asfPnw4MDDQ1NT0p59+OnLkCNZRtitUxsbGP//8M5b45MkT8Qy5sWPH+vv7oye53oU+V9gp2DV//PFH3759Y2JiMJ/Y2NgPP/wQ2xBzxvYUzbCXEaq7dOmC0K68WEBXVxfb2d7ePufZ6S1btsTnx8DAAHv2pS4uICIiIiKiUkMjLCwM/7yJw5JFJuVZ9P2EvYZ61sYGr/uQrTchLi6uf//+GNi8eXP+Dw+DlJSUMWPGnDlzZvv27Xldgk55wRb++OOPN23aJDZ4MXT79m0PD48aNWqsWbNG/AJCVIjEpRAhISGiWOjE5Rji5hcl+luDiIiI6L9Vso+HC3pla9QxHlY8QziRqqNHjwYFBYmb0ssqIiIiIiJ6y5SGHE5UIsTGxu7Zs8fBwYF3aCMiIiIiepsxhxMVhbS0tDVr1iCHe3h45H9/ASIiIiIiKt2Yw4neLB8fH1dXV3t7+0mTJg0fPnzIkCEFv10cERERERGVPszhRG9WZmbm4cOHMfDjjz/OnTtXea91IiIiIiJ6O5WG+6UTERHwfulEREREJQKPhxMREREREREVHeZwIiIiIiIioqLDHE5ERERERERUdJjDiYiIiIiIiIoOczgRERERERFR0WEOJyIiIiIiIio6zOFERERERERERYc5nIiIiIiIiKjoMIcTERERERERFR3mcCIiIiIiIqKiwxxOREREREREVHSYw4mIiIiIiIiKDnM4ERERERERUdFhDiciIiIiIiIqOszhREREREREREWHOZyIiIiIiIio6DCHExERERERERUd5nAiIiIiIiKiosMcTkRERERERFR0mMOJiIiIiIiIig5zOBEREREREVHRYQ4nIiIiIiIiKjrM4URERERERERFhzmciIiIiIiIqOgwhxMREREREREVHeZwIiIiIiIioqLDHE5ERERERERUdJjDiYiIiIiIiIoOczgRERERERFR0WEOJyIiIiIiIio6zOFERERERERERYc5nIiIiIiIiKjoMIcTERERERERFR3mcCIiIiIiIqKiUyJz+O9XExafjBmx6/aAzTfwvjTgwfaQODmOiIiIiIiIqBjTCAsLwz+2traiXJz9lZKx7tyjXaHxT9OfyyoVyemZLcwrLOphUVFPW1YREb1NEhMT8R4SEiKKha5hw4Z4v3//Pt5LxLcGERERUfFUYo6H/xmd3H/zjU0XHu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">

Click Users and groups

My New app I Users and groups 
Enterprse Applicat& 
+ Add user 
Edit Remove p Update Credentials 
Overview 
O 
The application will appear on the Access Panel for assigned users. 
Diagnose and solve problems 
irst 100 shown, to search all users & groups, enter a display nami 
Manage 
Display Name 
Properties 
NO application assignments found 
Owners 
Users and groups 
provisioning

Click Add user

Home > Default Directory > Enterprise applications I All applications > My New app Users and groups > Add Assignment 
Add Assignment 
Default 
Groups are not available for assignment due to your Active Directory plan level. 
Users 
None Selected 
Select Role 
Default Access

Click None Selected, pick users from the list and click Select. These users have now been given access to your application. However, as I mentioned earlier all users who are part of your Azure AD currently are able to login to your web app, we need to now configure the app so that only assigned users can access it.

Click Properties in your enterprise application and set User Assignment required to yes and click Save. (repeat this for your other application)

Home Default Directory 
My New app I 
Enterprise Applicati'H 
Overview 
> Enterprise applications I All applications > My New app I Properties 
Properties 
Save Discard Delete 
Enabled for users to sign-in? O 
Diagnose and solve problems 
Manage 
properties 
Owners 
Users and groups 
provisioning 
Application proxy 
Self-service 
Security 
Conditional Access 
permissions 
Token encryption 
Name * (D 
Homepage URL G) 
Logo @ 
Application ID O 
Object ID O 
User assignment required? C) 
Visible to users? O 
My New app 
MN 
Select a file

Now only users who are assigned to your application can login. You can test this now. Go to the first application url and login with one of the users you assigned. Then go to the second app (you shouldn't have assigned any users just yet.) and login. This time you will get an error.

You can now assign users to the second application and the error should go away when you attempt to login.

We’ve now set up our applications in Azure AD and limited access to each application. In my next post I’ll show you how you can then add users from outside of your organisation to these applications.

Adding Security Policies To Azure API Management

The Azure API Management service allows you to publish your APIs both internally and externally and to control who and what can access them. Out of the box you will get a standard API key for each of you users who sign up to the API, but this is often not enough meet the security requirements for you or your partners. API Management allows you to add a more fine grained security model you each of your APIs and this can be done using the policy feature. Policies are used for more than just security and there are numerous policies that allow you to change the behaviour of your API through configuration. Documentation for the types of policies can be found here. Sample policy examples can be found here.

Two policies that I am going to discuss here will allow you to restrict access to your API through IP Whitelisting and through validating JWT claims. I will also discuss how you can put different controls onto your API for different partners.

Policies can be set at different levels and the documentation will highlight the areas where they are applicable. For security policies I am going to talk about protecting at the API level and at the product level. Adding a policy at the API level will be applicable to all subscribers to the API whereas adding the policy at the product level will be applicable to all subscribers to the product. A product can contain multiple APIs and and API can be in multiple products. So we can add in protection at either level depending upon what your exact requirements are. The policies are the same but their impact will depend upon where they are applied.

 

Lets start with API level policies. To add or edit policies then you need to navigate to your API in the Azure Management portal. Then click on the API option, then click on the API you wish to protect

image

The easiest way to add a policy is to click the Add Policy link in the inbound section.

image

Click Filter IP Addresses and Add IP Filter

image

This form allows you to add ranges or single IP addresses to both allow or deny.When you have finished click Save.

You will now see the policy in the policy editor view. If you are happier to add this in manually or want to copy this and version control the config then you can access this via the Code Editor menu on the Inbound processing policies box

image

image

Appling this policy on the API means that only IP addresses within this range can access this specific API and can be useful to ensure that this specific API is blocked from being accessed regardless of the product has been subscribed to. Its also useful if you want to block access from specific IP addresses. However, you may have different partners who have different security arrangements or that you want to give different permissions to . To allow for this you will need to add the policy at the product level.

To edit the policy at the product level, click Products, pick the product you want to secure.

image

In this example I have a new More Secure API that I’ve created and there’s an access control section which allows you to pick the users who have access to this API

image

So I’ve immediately blocked access to this API to guest users and we can add user authentication to  the API if we want, such as OAuth 2.0 and OpenID connect.

However, this post is talking about adding security policies and if we want to allow only specific IP addresses to access this API we can edit the policy at the Product level. To access the policy definition click Policies

image

You’ll notice that this is just the editor view and the easiest way is to add the policy at the API level using the wizard and copy the config to here. Products are a mechanism to allow you to group and protect APIs which means that from a management point of view you could create a product for each of your partners making it easier to maintain the security details for each and make it easier to disable access and remove only the security policies that apply to the specific partner. Managing this at the API level means that you will end up with a large number of security policies relating to a large number of partners making it difficult to manage. Security polices at the Product level are more important when you want to do some specific protection like checking claims in a signed JWT. The Product level policy allows you to have different signing keys for each product meaning that you can have different signing keys for each of your partners (assuming one product per partner).

image

This policy requires a JWT signed with the key eW91ci0yNTYtYml0LXNlY3JldA== and that also has the claim admin=true. If there is an error then 401 is returned with the message “You have failed the security checks please contact your administrator”

To summarise, we can add policies at both API and product level. Product level polices allow us to create a new product for each of our partners and then add specific security policies to the product tailored to our specific partners needs. The product level policy makes it easier to manage the security policies at a partner level but we can allso add global security policies at the API level such as blocking access from certain IP address ranges. Policies can do a lot more than security so check out the links at the start of the post for further information

Azure Key Vault Logging and Events with Log Analytics

Following on from my previous blog post (http://blogs.recneps.net/post/Setting-up-Azure-Key-Vault-with-Audit-logging) which explains how to set up Azure key vault with logging enabled, this post explains how to access the details of these logs and also to create an alert so you can see if someone is accessing the key vault from an unknown ip address (for example)

Open the Azure portal and navigate to the Resource Groups section and pick the resource group that we configured last time which contains the key vault and log analytics resources

image

Click your log analytics item, to open Log Analytics.

You can then select Log Search

image

This screen allows you to create your own query or select from existing ones.

image

Selecting “All Collected Logs” will show you the logs for the last day. I’ve highlighted the areas where you can change the time period, see the query and also click on Advanced Analytics to give a richer environment for analysing your logs.

image

If you want to query just for the Key Vault Audit logs then you can use the following query:

search * | where Category=="AuditEvent"

image

This will default to a list view, but clicking the Table button will format the data in an easier to read table.

image

You can sort and filter on the column headers. This can also be achieved using the order by clause as follows:

search * |where Category=="AuditEvent"  | order by TimeGenerated desc

A blog post discussing the query language can be found here

We are interested in all calls where someone has tried to access a Secret from the key vault. For that we are looking for an AuditEvent with an OperationName of SecretGet. If we also want to restrict the columns we retrieve then you can use “project” e.g.

search * | where Category=="AuditEvent"  and OperationName == "SecretGet"
| order by TimeGenerated desc
| project TimeGenerated, OperationName, CallerIPAddress, ResultSignature, requestUri_s

image

Now we are familiar with writing queries we can look at alerting. I’d like to set up an alert when the key vault is access from an IP Address other than the one where my application is running. This can be done as follows:

search * | where Category=="AuditEvent" and CallerIPAddress != "51.140.184.51"

This ip address is actually the Azure Portal and is shown when you view the resource group that contains the key vault.I’m using this ip address so that I will actually get an alert (at the wrong time) when my application runs

Click New Alert Rule

image

The following screen should appear

image

The Alert Target should be the Log Analytics we’ve been using and the Target Criteria (when clicked) should show the query we’ve just written

image

We need to configure the rule for when this alert should be triggered. I’m interested when at least 1 attempt has been made in the last 5 minutes to access the Key Vault from an unknown location, so I set the threshold to be zero and click Done. We’ve now configured the logic to determine when the event is fired. Now we need to say what we want to happen when it fires.Firstly we need to give the alert a name and description

image

Now we need to configure how we are alerted. For this you need to create an action group. An action group allows you to define a collection of activities that will happen when the alert is fired. Click New Action Group

image

Action Types can be any of the following:

image

An action group can have multiple actions and you can select both email and SMS in a single action.Once you have created your Action Group you need to select in then click “Create alert rule”

image

Your alert is now set up and running. You can view/edit alerts by selecting Monitor in the Azure Portal

image

then click Alerts (preview), you will be able to see the alerts that have fired.

image

Click Manage Rules to edit the alert.

When the alert is fired I will get an email containing the details of the alert.

Log analytics is a powerful tool and whilst this series of posts has been related to auditing of Key Vault we can use log analytics for a wide variety of log sources such as Application Insights. We can also use the same mechanism for alerting to these other log sources,

The next post is a video that shows you how to connect existing log files to log analytics