Steve Spencer's Blog

Blogging on Azure Stuff

Using Azure DevOps to deploy to an Azure Function Deployment slot

What is a deployment slot

A deployment slot is effectively another Azure function that is linked to your production instance. A deployment slot allows you to deploy your function to the slot and be able to test it separately to the production instance. It will have its own url and access key. When you are happy with the function you can then make it live by swapping the production and staging slots. The deployment in production becomes staging and the deployment in staging becomes production. This means that if there are issues with the new deployment you can easily revert back by performing another swap. There is minimal downtime during the swap and is quicker than a direct deploy to production. You can use Azure DevOps to deploy your new changes to the staging slot instead of production and then perform either a manual or automatic swap to production.

Creating a deployment slot

In Azure portal. Navigate to your Azure function and click on “Deployment slots” then “Add slot”

clip_image002

Enter the name of your new slot. Note : You can have more than one slot if you wish and each one can be deployed to separately.

image

You now have a new slot and you can manually deploy to the slot from Visual studio as you have been doing with your current production slot.

Creating a Release Pipeline to deploy to the slot

In Azure DevOps click on “Pipelines” then “Releases”

image

Click “New pipeline” and search for “function”

image

Select “Deploy a function app to Azure Functions with slot”. A new pipeline will be created

image

Close the dialog that appears and click on the Stage 1 link

image

I generally do not want to automatically swap to production immediately so you can delete the second task by right clicking on the “Function App – Slot Swap” and selecting “Remove selected task(s)”

image

Now you should be left with just the deployment task. Select the Azure subscription where your current function app is deployed and select all the other properties relating to the function app and staging slot

image

image

Now we need to tell the release what build we want it to use to deploy. Click on “Pipeline” then click “Add an artifact”

image

Pick the correct build from the drop down

image

If you want to make this deploy automatically after each build is completed click the little lightening icon on the artifact

image

Click to enable the continuous deployment trigger.

image

Then click “Save”

image

To test this out, click “Create release”

clip_image026

Then “Create”

image

You should see a notification saying the release has been created. Clicking the link will take you to the release where you can see the status of the release deployment.

image

image

image

You may wish to rename your pipeline. Click “Edit”

clip_image036

Then click the pencil to edit

clip_image038

Enter the new name then click “Save”

image

Your release is now complete and should run each time a build is completed, deploying the latest artifacts from the build into the staging slot. Which is now ready for testing.

Testing a Deployment Slot

Back in the Azure portal, click “Deployment slots” on your Azure function.

image

Click on the “Staging” slot the click “Functions”

image

Click on the function you want to test

image

Then click “Get function url”

image

This will give you a url and key that will allow you to test and it is not linked to your production slot, although if your configuration is pointing to the same database as production it will connect through to that.

Swapping slots

Once you are happy with the deployment, you can manually swap the staging slot into production. Go back to the deployment slots blade in the Azure portal and click “Swap”

image

Select the slots you want to swap (assuming there are more that 2)

image

Click “Swap”.

Your two deployments will swap and the staging will now be live. If there are issues with staging and you need to revert, just click “Swap” again. Be aware that if you have a new build/release happening then the new release will overwrite the staging slot and therefore lose the old production deployment. It is possible to chain deployments so that the build triggers a deployment to the test environment and only triggers a release to production if the release have been manually triggered. It is also possible to have an approval step so that a production staging deploy can only happen once someone has approved it. Both these options will stop the old production instance being overwritten until you are ready for it.

Automating Azure AD Entitlement Management with Graph API

This post builds on two previous posts: one that introduced Entitlement Management and the other that introduced the Beta version of Graph API. I will show what is available within Entitlement Management for automating with Graph API.

The documentation for Graph API is here and is currently in Beta so you will need to use the Beta libraries to access.

Let’s assume that you have already setup your access packages and want to make your own portal to allow users to select the packages they want.

You’ll want to list the packages that are available first to allow the user to pick the package they require. This can be done using the Access Packages endpoint

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var accessPackages = await graphClient.IdentityGovernance.EntitlementManagement.AccessPackages
     .Request()
     .GetAsync();

This will return a list of access packages the user can request access to. You will need to ensure that the user has been assigned the correct permissions: EntitlementManagement.Read.All or EntitlementManagement.ReadWrite.All

Graph API will also allow the user to request access to a package. For this the user will need to create a request using the Create accessPackageAssignment request

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var accessPackageAssignmentRequest = new AccessPackageAssignmentRequestObject
{
     RequestType = "AdminRemove",
     AccessPackageAssignment = new AccessPackageAssignment
     {
         Id = "a6bb6942-3ae1-4259-9908-0133aaee9377",
         TargetId = "46184453-e63b-4f20-86c2-c557ed5d5df9",
         AssignmentPolicyId = "2264bf65-76ba-417b-a27d-54d291f0cbc8"
     }
};

await graphClient.IdentityGovernance.EntitlementManagement.AccessPackageAssignmentRequests
     .Request()
     .AddAsync(accessPackageAssignmentRequest);

The code above was modified from the examples and more scenarios are available there too.

The following request types can be used:

  • UserAdd
  • UserRemove
  • AdminAdd
  • AdminRemove
  • SystemRemove

So the request can be used to add and remove assignments by either the User or an Admin.

You can view the assignments for a user by using the Access Package assignment endpoint:

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var filterByCurrentUser = await graphClient.IdentityGovernance.EntitlementManagement.AccessPackageAssignments
     .FilterByCurrentUser(AccessPackageAssignmentFilterByCurrentUserOptions.Target)
     .Request()
     .GetAsync();

These end points should be enough to get you started with automating Entitlement management but there are more features that could be automated if you require them. All the resources that are currently available can be found in the Entitlement management API documentation

Introduction to Azure Entitlement Management

In Previous posts I’ve talked about how to add applications to Azure AD for Single Sign On (Part 1, Part 2) and also how to automate user management using Graph API and also how to use Graph API to assign users to applications. This post will be about how you can then manage the users access to the applications in a more controlled way and also how you can delegate some of that management to the teams that user them.

Azure Entitlement Management is an Azure AD service, part of Identity Governance, that allows applications and services to be packaged together to allow for simpler management. For example when a new member joins your team there is always a period of uncertainty about whether they have the access they require and it is not until they try to access a specific system that you find out that they need adding to a specific group, application or SharePoint site. This always takes time especially if you are a larger company and requires a ticket raising and often approval sought before the access will be granted, often losing a number of days before access is given. Identity governance allows all the groups, applications and sites to be packaged together in one or more access packages so that a new user can be assigned to one access package and subsequently be given access to the services they require.Requests to be allocated to an access package can be made by the user requiring access and approval workflows can be added if required.

This can also be extended to users outside of your organisation, whether they are collaborative users who are part of your team or whether the users are accessing the digital services provided by your organisation.For this the users will access using Azure AD B2B. Another feature of Identity Governance is access reviews. A users access can be periodically reviewed, either automatically or manually to determine whether the user still required access. If access is no longer required or the user does not respond within a certain timeframe then access can be revoked. Therefore allowing users to be managed in a more efficient manner and removing access when it is no longer required, which is especially useful if a user has left an external organisation and you were not informed.

There is a hierarchical structure to Entitlement Management starting with a Catalog. A catelog contains Resources that can be added to Access Packages. An access package contains a collection of Azure AD groups, Applications and SharePoint sites, along with rules determining which users are allowed to be assigned to the package and an associated approval workflow. Management of access packages can be delegate to a subset of users who are close to the teams and customers requiring access.

To create a Catelog, got to the Azure portal and click on or search for Identity Governance:

image

The in the Entitlement Management section click “Catelogs”

image

To create a new Catelog, click “New Catelog”

image

Enter some information relating to the catelog and decide whether the Catelog is to be used by External users i.e. B2B users outside of your organisation:

image

The catelog is a container for the resources you want to package and can also be used to delegate the administration and there are a number of different roles that can be applied.

To Add resources to the catelog, Open the catelog by clicking on it.

image

Click on “Resources”, then “Add resources”

image

image

In my example we will be adding a number of groups and a number of applications to the catelog:

Click on “Groups and teams”:

image

image

Pick the groups you require and click Select.

image

Now click “Applications”

image

And pick the applications you require.

image

Click “Add”. Your resources are now assigned to the catelog. This has not provided any access to the resources, just added them to the catelog where they can be later added to one or more access packages.

You may now want to delegate some of the responsibility to managing the catelog. Roles can be assigned to users and details of the roles can be found here.

image

You can see that you can assign users to the different roles, click the role you want to assign and select the users you wish to assign the role to:

image


You can see here that I’ve assigned the access package manager to Fred. This will allow him to create new access packages based upon the resources that have been assigned to the catelog. He will not be able to assign any other resources that are not in the catelog. Jane has been given the package manager assignment role. This will allow her to be able to assign users to the packages that were created by Fred.

image

To Create an access package, click “Access Packages”, “New access package”

image

Populate the form:

image

Click “Next:Resource roles”

image

Assign the applications and groups you need and select the roles (if any have been configured)

Now you need to decide who is allowed to access these application

image

I’ve selected all users including guest users. Note, A guest user must first be invited into your Azure AD before they can request access to a package. I’ve clicked on the approval workflow. Now click “Add approvers” and select the users who are the approvers.

The next stage allows you to collect some data from the users to help the approvers determine whether access is allowed or not.

image

The next page is all about the access lifecycle. This allows you to configure a duration to the access and whether an access review is required or not.

image

The last page allows you to review the configuration and then click Create.

image

Unfortunately, I didnt complete all the sections correctly:

image

Clicking on the items allows you to navigate back and fix your issues:

In Lifecycle, I didnt click on whether an access review is required or not:

image

Lets configure a quarterly access review:

image

The users will be notified every quarter and asked whether they still require access or not. When you have fixed all the issues, click “Create”

image

On the overview screen, there is a link that is unique to your Azure AD. The link allows users in your organisation, based upon the setting in the requests section, to request access to this package. We configured it for all uses within your Azure AD.Clicking this link will take you to the site to request access.

image

Select the package and click “Request access”

image

The user will be presented with an access form with the questions you configured:

image

image

Complete the form and click “Submit”

The user can see the status of their request:

image

As an approver you can see what approvals are pending at https://myaccess.microsoft.com

image

You can review the access request by expanding the Request Details and Package details and then Approve or Deny the access request

image

Upon approval the user will be able to see their access packages in their my access portal, along with the expiry date.

image

The user can also view the details of the request in the “Request history” section

image

I hope you can see that Entitlement management will help you add some governance around your user management along with self service and user management delegation. I will be following up this post with one about automating the user assignment using Graph API, so keep a look out for it.

Identifying where the credentials for an Azure AD B2B user originate

After a conversation with Microsoft where we were discussing users who are having issues signing in with B2B, I thought it would be good to share what I’ve learned.

When you using Azure AD  as the identity provider for your applications and are using B2B (Guest) accounts to allow external users to access your applications, you will at some point encounter users who are unable to sign in. There are a number of issues that could arise and the information against the users profile will help you to diagnose where the problem is likely to be.

If you go to the Azure AD portal and search for the user by their email address and click through to their profile, I’ve highlighted a number of areas of interest.

image

The box on the right shows whether the user has accepted the invitation or not. The bottom box shows whether the user has been blocked access to your Azure AD. Maybe they were a user previously on a different application and for some reason their access has been blocked. If this is the case then it is best to look at the Groups and Applications that the user is already assigned to before you unblock the user.

If the user has accepted the invitation then the final box (“View more”) will give you some useful information. Expanding the box will show you where the users B2B account originates:

image

This one shows the user has a Microsoft account.

The values can be:

  • Invited User: This user has been invited but has not yet redeemed an invitation.
  • External Azure Active Directory: This user is homed in an external organization and authenticates by using an Azure AD account that belongs to the other organization.
  • Microsoft account: This user is homed in a Microsoft account and authenticates by using a Microsoft account.
  • Windows Server Active Directory: This user is signed in from on-premises Active Directory that belongs to this organization.
  • Azure Active Directory: This user authenticates by using an Azure AD account that belongs to this organization

Further details can be found here

The source can help you to tailor your response to the user. For example, if the Source shows External Azure Active Directory, you know that the user is signing in with their corporate account and if they are having issues signing in then it is likely to be an issue at their end. If it shows Microsoft Account then they need to use the credentials they use to access their Hotmail, One drive or personal computer (if they have it connected to their Microsoft Account) and you can point them to the relevant pages for assistance.

Once they have signed in correctly they may still have issues accessing your application. You would need to look at the configuration of the application, Conditional Access (Note, conditional access could be an issue at their end, if their corporate IT have blocked B2B access at their end for example), group configuration etc.

I found that being able to identify where the users credentials are sourced meant that I could provide a far better support response to my customers and this resolved a lot of the issues.

Using Azure AD Conditional Access to Trigger MFA

Cloud hosted services and collaboration mean exposing services to a worldwide audience, but it also exposes you to malicious attacks and identity is one axis where attacks take place. Usernames and passwords are constantly being obtained either through hacking, social engineering or buying. Once obtained they can be used to gain access to a variety of system and single sign-on makes the scope of attacks larger. It has long been recognised that having multiple levels during authentication makes it harder for an attacker to gain access. Microsoft have been involved with identity for a long time now with their services such as Hotmail, XBox Live and Azure and they have used this experience to build and enhance their security models to incorporate Multifactor Authentication (MFA) into their systems. MFA allows you to use an additional piece of information that is usually generated at the point of entry and is not something that is remembered. This information is usually generated and presented on something that you have in your possession such as a Mobile Phone, RSA key or FIDO token. This adds an additional layer of protection as it means the attacker also requires the same device in order to gain access. When building your applications it is sensible to incorporate MFA into your design and Microsoft Azure has the Conditional Access service to help you build this extra layer of security into your applications.

Conditional Access allows you to create a set of rules (policies) about the access a user is attempting to determine whether the user is allowed access, whether they are required to user MFA or whether they are blocked from access. Conditional Access policies use a set of signals that could be things like being a member of a specific group; accessing a specific application; IP address/location information; the device they are using or if Identity protection is enabled there are a set of AI models applied that give the user or login a risk value.Rules are applied to these signals and a decision is made.

In order to use Conditional Access your Azure AD tenant will require a P1 license or Microsoft 365 Business Premium for each user. 

To setup Conditional Access Policies, navigate to the Azure Portal and search for Conditional Access

image

Click “New Policy”

image

You can configure the group membership requirements, which apps the rules apply to and the conditions that apply. When a user signs in each policy is evaluated to see which ones apply to the users. Each of the conditions are evaluated and any policies that match all the conditions will be applied to the user. This is an important point because if you make the policies too restrictive then a user may not match any conditions and they will be given access without applying any access controls. This is especially important if you are expecting access to be blocked if the conditions are not met, which is not the case. You will need to create a specific policy for that which blocks the access.

When creating a policy, enter a name for the policy and then click users and groups to determine who the rules apply to.

image

Here you can include or exclude sets of users. Whether its all users, your guess/external/B2B users, specific roles or specific users or groups. For example you may apply this rule to All users and exclude users who are members of a specific group. If you apply the rule to all users then you will get a warning that might cause you to lock you out of access. In this scenario you could exclude users who are part of the admin group so at least a small number of people will gain access.

image

Selecting a user or group brings up the user/group picker. Select a group.

In addition or instead of, you can pick an application or group of applications that will cause the policy to be applied if the user tried to access them. Whether you use this or groups will be down to you. It depends how you give access to the applications. If the number of groups to access the applications is complicated then you might want to apply the application here, if for example you use group membership to control access to the application then you can just use the same group in the policy instead of the application.

image

Picking the all applications has the same warning as all groups. For this policy we’ll just stick with group membership so will select None

The next part to pick is the condition for the policy.

image

Be aware here that both User risk and Sign-in risk can be applied here, but will only give you a valid value if Identity Protection is also enabled in your tenant.These conditions will return a percentage value based upon whether Identity Protection believes the user account has been compromised or the sign in attempt is not authorised. Information about the information monitored to generate the risk can be found here

Device platforms looks at the type of device that is trying to connect. This works well for machines that are internal to your organisation and are managed by Microsoft Intune device compliance policies. User agent strings will be used for External users , but these can be changed so are not a reliable condition for B2B users.

image

Locations allows you to configure trusted locations where access is allowed from and access is blocked if the access if from elsewhere. I’ll talk about this in a future post.

image

Client Apps allows you to configure which apps are allowed access and which are blocked.

image

Finally Device state

image

This allows you to exclude compliant devices from the policy.

image

Now you have configured all your conditions you now decide what action should be taken if those conditions are met. Here  you can grant or block access

image

There are more conditions that need to be met to allow access. MFA is one of these. Selecting MFA will force the user have to use a secondary authentication device before access can be gained. Unlike the policy conditions, failure to meet the conditions at this stage will block access. If a user manages to get through the conditions but doesn’t have a Hybrid joined device or fails the MFA challenge then they will still not gain access.

The final option is for Session which is used to determine whether the user needs to be challenged again for MFA. This can be set in the Sign-in frequency option:

image

Now we have a choice about how to apply the policy. Whether to enable it or set it to report only. If you have a complex set of criteria that you want to enable and not sure whether there will be issues you can set the policy to Report Only and this will appear in the sign in logs showing what the rule outcome will be. You can run it on the user population and review the logs to see if the policy breaks anything. This will also be the subject of a future post. For now we will set the policy to On and click Create. This will now be applied to all users and those that match the policy will be presented with the MFA challenge.

The policy we’ve just created will present all users who are NOT in the Alpha Team group with the MFA challenge and members of Alpha team will be allowed to sign in without MFA.

Its a good idea to plan your conditional access policies so that there are not too many complex policies that could end up with scenarios where users are given access without out the additional security of MFA. There are also limitations on the number of policies that can be applied to a user after which they policies are ignore. I believe the limit at the moment is 100 but I can’t find this in writing anywhere.

Conditional access allows you to build extra layers of security into your app and data access  processes and tailor the access model to suit your needs. The next posts will cover reviewing and diagnosing policies and also restricting access based upon IP addresses.

Delegating User Management using Azure Administrative Units

Azure Administrative Units allows an administrator in Azure to separate out the management of specific users and groups and delegate management to a specific set of users. This may be to allow for access to specific applications or to isolate the management of a specific set of users due legal restrictions based upon their location, nationality or the data they are accessing, for example. Azure Administrative units require and Azure AD Premium P2 license for each user you wish to delegate as an Administrator.

In order to separate out the users you must create an administrative unit, assign the users and groups you wish to managed to the unit and then assign users to be the admins.

In the Azure portal, navigate to the Azure Active Directory blade and click on “Administrative units”

image

To Create an Administrative unit click “Add”

image

Enter a name and description the press “Review + create”

image

You can assign the users you want to delegate the administration of the Administrative unit on this page, click “Review + create” as we will be assigning the admins later.

image

Now click “Create” & the Admin unit should now be created.

image

We now need to decide what and who we want to manage within this unit. Firstly we’ll add some groups. Click on the Admin unit then Click Groups

image

Click Add and select the groups you want to put in this Admin unit.

image

Then click “Select”

image

Now you can add your users, click “Users” & “Add member”

image

Select the users you wish to add to the Admin unit and click “Select”.

image

Now we have our Admin unit set up with two groups and two users. We now need to assign an administrator for this unit. Click “Roles and administrators”

image

This displays the different roles that can be used to manage the Admin unit. This allows you to have multiple administrators of the unit with different permissions. We’ll just create a single Administrator who is allow to manage the users into the groups we have assigned. Click “Group administrator”

image

Click description if you are unsure what the role does. You will get a description plus a list of the finer grained permissions included in the role. Click “Add assignments” and pick the user you wish to assign to this role, then click “Add”.

image

You can repeat this for the other roles if you wish. Your admin unit is now setup.

Now login with the administrator of the admin group who you added previously. This user will need to have already been assigned the Azure AD Premium P2 license and the user should be able to assign Fred and Jane to the groups Application 1 and Alpha Team.

In Azure AD, click Users, then click Fred.

image

Now click “Groups”, then “Add memberships”

image

and select “Alpha Team” and click “Select”.

image

Alpha Team should now be assigned to Fred.

Click “Add memberships” again, but this time select the “Beta Team” group and click “Select”

image

You will see a notification saying that you do not have the correct privileges to manage that group. Similarly if you try to add any user other than Jane or Fred to any of the groups you will get the same error.

So,by using Azure AD Administrative units I’ve shown how you can delegate the management of certain groups and users to specific individuals. Administrative groups will allow you to organise the management of your Active Directory and delegate management, helping you to reduce the risk by providing the user management with a lower level of privilege than just by giving all your users administrators the global Group Administrator role. This will allow you to partition off sensitive groups and applications and restrict the users who are able to manage those, whilst extending the administration to a wider set of users.




Copying and unzipping files using Kudu on Azure App Service

Kudu is a useful tool that is part of your Azure App Service. I posted a video showing how you can access the Debug Console of Kudu and edit files. In this post I’ll show how you can upload files to your website and also how you can unzip files.

Starting with an empty site, navigate to the Kudu console via the Azure Portal App Service Advanced tools then Debug Console –> CMD

image

To upload a file drag one from Windows Explorer and drop it on the left hand side

image

After uploading the file should appear in the list

image

If you want to delete the file click the circle icon of the file you want to delete:

image

To upload a file and also unzip it there are two options. You can upload the file using the method above by dragging the file in. Then in the command window run the unzip command.

image

Alternatively you can drag the zip file onto the right hand side of the screen.

image

This will upload the file and unzip it in one action.

So with my previous video and this post I’ve shown you how to upload, unzip edit and delete files in your Azure App service. Kudu has helped me to access the files, make changes and debug in scenarios where I don’t have access to my normal tools and I hope you find it useful too.

Custom Application Roles in Azure AD

Previously I’ve talked about how you can control access to your web applications in Azure AD (Part 1 & Part 2) and also how to use Role Based Access Control (RBAC) to manage access to resources in Azure. This post will build on these previous posts and show you how you can create your own custom roles for use in your own web applications and how you can use these roles to control access to parts of your application.I’ll use the same example used in Part 1.

Firstly you need to created the roles for your application to use, assign the roles to users and finally change your code to make it role aware.

To add roles to your application. Navigate to the Azure portal and click on Azure Active Directory and App Registrations. Select the Web App you created previously.

image

Click on “App roles | Preview” then “Create App Role”

image

Enter the role information and click Apply and repeat for all the roles you require.

You should now see your roles in the grid:

image

I’ve added a standard user role and a test administrator role.

To assign these roles to users, Navigate to the Enterprise Applications blade and click your application. Then select “Users and groups”

image

To Add roles to an existing assigned user, tick the user and then click “Edit”

image

Select the role and click “Select”

image

You should now see the role is assigned to the user. Similarly to add a role to a new user click “Add user”

image

This time you need to select the new user and then the role:

image

You can add multiple roles to a user by repeating the Add user process.

image

Here I’ve added both new roles to one user.

You are now ready to user these roles in your application.

The sample code already shows how to view the claims for a user.

image

When I sign in to the application with the user that has two roles I see the following entries in the claims table:

image

Adding the roles to the application and the assigning the roles to a user is enough to make them appear as roles in your application when the user signs in. There is a limit to the number of roles that an application can have. These are stored in the manifest of the App Registration. There is a limit of 1200 items in the App Registration Manifest and this includes all the configuration items not just roles.

There are a number of ways in which you can use Roles in code. Firstly in your views you can add conditional code to limit what a standard user can see

@if (Request.IsAuthenticated && User.IsInRole("Test.Admin"))

{

<h2>You Are An Admininstrator</h2>

<br />

}

When you sign in with the Test,Admin role you will get this additional text which is not visible for the User role

image

You can also control access at the controller and controller action levels by adding the Authorize attribute on the controller or controller action:

[Authorize(Roles = "Test.Admin ")]

public class ClaimsController : Controller

{

or for multiple roles

[Authorize(Roles = "Test.Admin,User")]

public class ClaimsController : Controller

{

at the action level:

[Authorize(Roles = "Test.Admin")]

public async Task<ActionResult> Index()

{

}

or both

[Authorize(Roles = "Test.Admin,User")]

public class ClaimsController : Controller

{

        [Authorize(Roles = "Test.Admin")]

        public async Task<ActionResult> Index()

        {

        }


        [Authorize(Roles = "User")]

        public async Task<ActionResult> Index2()

        {

        }

}

In this example the user needs either the User or Test.Admin role to access the controller but only the Test.Admin role can access the Index action and the User role can access the Index2 action. This allows you to put controls in at multiple levels and provide a more custom experience for your users.

App Roles makes it easy to add custom roles to your application. If you have a higher Azure AD subscription you can assign these roles to groups and assign the groups to the applications. This means that you can add users to groups to assign the roles rather than adding them to each individual user. I can have a Standard user group that has the User role assigned and all users in that group will have the User role passed through to the application.

You now have Role Based Access control in your Azure AD application and can start to build your application features out based on the roles you define.

Accessing secrets in Azure Key Vault using a Managed Identity

With any key/password store I always thought that the weak link was the credentials used to access it. If that single point of failure was compromised then all your secrets would be vulnerable. Microsoft have overcome this by creating the Managed Identity. A Managed Identity is generated by a resource within Azure and can be configured to access resources that use Azure AD for authentication. As the Managed Identity is generated by the resource there are no credentials to store anywhere and code running in the resource can use this built-in identity to access other resources. This is specifically useful for Key Vault because we can now give access to Key Vault to specific resources without the need to store any credentials anywhere. This post will show you how to access Azure Key vault from an App Service using a Managed Identity to retrieve a secret for use in accessing other services.

So I have a web site deployed to Azure App Service and in order to access Key Vault I need to create a Managed Identity for the App Service. In the Azure Portal navigate to your App Service and click on the Identity blade

image

Your Manages Identity status should be Off. Click it On and then hit Save. This has now enabled your Managed Identity. The App Service Identity now exists in your associated Azure AD tenant and can be assigned to resources. This means that any code I write and deploy to this App Service will be able to take advantage of this built in identity to access the resources I need. In this example I want to access Key Vault. I therefore need to enable this new user in Key Vault. To do this I need to create a new access policy in Key Vault for this user.

Navigate to your Key Vault and click “Access policies”

image

Click “Add Access policy”

image

I’m interesting in just secrets from this Key Vault so I’ve selected the Secret Management template then clicked “None selected”. You should now see a new Principal blade appear. Type the name of you App service in the search box and select the principal that appears. Now click the “Select” button followed by the “Add” button. If you have not done this stage then you will get an error like this, when trying to access the Key Vault:

Service request failed. Status: 403 (Forbidden) The user, group or application 'appid=<app id>;oid=<oid>;iss=https://sts.windows.net/<tenantid>/' does not have secrets get permission on key vault 'yourkeyvault;location=westeurope'.

You should be setup now to access the secrets from code. there is a quick start guide produced by Microsoft to help with this.

Two packages are required to access Key Vault secrets.

Azure.Security.KeyVault.Secrets & Azure.Identity

With the packages installed the code to access Key Vault is simple.

var credential = new DefaultAzureCredential();
var client = new SecretClient(new Uri("https://yourkeyvault.vault.azure.net/"), credential);
var secret = await client.GetSecretAsync("YourSecret");
string actualSecret = secret.Value.Value;

Once this code is deployed to your App Service, the DefaultAzureCredential will automatically pick up the Managed Identity and allow you to access the secrets stored in it. Create a SecretClient, point it at your Key Vault and add the Managed Identity credential. Now you can retrieve the secret and use it.

Managed Identity is another tool to help you make your applications more secure. There is now a reduced risk of compromise from a mishandled Key Vault credential that you’ve stored somewhere safe. The Managed Identity cannot be used from anywhere other than code running in your App Service.

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