Adding CORS to an Azure function app sounds easy but when you run it in a pipeline it is a bit more difficult. If you already added the origin to the list, a new entry is added when you run the pipeline for a second time. See this bug report for more information.
Here is a script to check if an origin is already added. If not, add it and otherwise skip the origin.
Write-Host"Check if allowedorigin '$item' is already set"
$missesOrigin=az functionapp cors show--name"$FunctionAppName"--resource-group$ResourceGroupName--query"contains(to_string(length(allowedOrigins[?contains(@, '$item')])),'0')"
if($missesOrigin-eq"true"){
Write-Host"Add allowedorigin '$item'"
az functionapp cors add-n"$FunctionAppName"--allowed-origins$item
Azure B2C has the capability to manage custom user attributes. Those attributes are custom extension on the Azure AD profile in the background. But how do they work and how can you access them with the Graph API?
In this sample, we are going to create a custom attribute called “GlobalAdmin”. It’s just a boolean for simplicity.
You can get the details of the user with the ObjectId using the url: https://graph.windows.net/{{tenant}}.onmicrosoft.com/users/fdabad31-92bf-43f7-8370-53c280ef042b?api-version=1.6 When the attribute is new, you won’t find the attribute on the user. Not even with the default value (in our case false because of the boolean).
Set a Custom User Attribute
To set the custom created user attribute we need to know where the custom attribute is coming from. An B2C user attribute is an extension to the Azure AD. Just as you would do with the regular Azure AD. You can imagine that if there is a big Azure AD and there are many applications connected to it. So Microsoft decided that an extension belongs to an application.
In our case, B2C it self is an application on top of the Azure AD. So Azure B2C has an application (app registration) in your Azure AD tenant. You can see this, when you navigate to the Azure AD blade in the Azure portal and go to the app registrations. When you click on the “All applications” you will see the default “b2c-extensions-app” application. You can also navigate to new preview blade in B2C it self.
You need the “ApplicationId” (ClientId) of that “b2c-extensions-app”. So open it, and copy it. Do not change anything on this application otherwise your Azure B2C can be broken!
We have all the information that we need, so let’s set the custom attribute. Create a new postman request and use the same url as getting the user detail information with the ObjectId. Set the type of request to “Patch” and add a header “Content-Type” with the value “application/json”.
But in the body the fields (attributes) you want to set. Let’t practice with the “displayName” of the user using the following body:
C#
1
2
3
{
"displayName":"Ralph Jansen2"
}
Hit send and the return code will be a 204 No Content. When you get the user, you will see the updated value. It can take about 15 seconds before the update is propagated over the whole world.
Now that is working, let’s update the custom user attribute “GlobalAdmin”. The attribute belongs to an application. In our case the applicationid is “08b93729-c048-4e64-8fba-48a4e98fdb98”. An Azure B2C user attribute extension will have the syntax “extension_b2cApplicationIdWithoutDashes_attributeName”. So this will result in “extension_08b93729c0484e648fba48a4e98fdb98_GlobalAdmin” in our case. So let’s put it in the body with the value true (because our attribute is a boolean) and hit send.
Get a Custom User Attribute
Let’s see the result by getting the user details again with the ObjectId. You will see the new attribute on the user (can take again a few seconds).
Searching a user in Azure B2C with the graph api can be difficult. You need to know which field you need to get the right information. The documentation (if any) is always behind. Hopefully this post will help someone that needs to get some user information from Azure B2C.
Accesstoken
You need an access token to query the B2C tenant. To get an accesstoken, follow my other blog that gives an introduction to Azure B2C.
Getting users
Above you see an example for getting all the users from your B2C tenant. Below you see a list for other queries that are more advanced. Change the tenant name.
Get all users https://graph.windows.net/{{tenant}}.onmicrosoft.com/users?api-version=1.6
Get User by displayName https://graph.windows.net/{{tenant}}.onmicrosoft.com/users?api-version=1.6&$filter=displayName eq ‘Ralph Jansen’
Get User by objectId https://graph.windows.net/{{tenant}}.onmicrosoft.com/users/fdabad31-92bf-43f7-8370-53c280ef042b?api-version=1.6
Get User by otherMails, userPrincipalName, mail https://graph.windows.net/{{tenant}}.onmicrosoft.com/users?api-version=1.6&$filter=(otherMails/any(x:x eq ‘info@sample.com’) or userPrincipalName eq ‘info@sample.com’ or mail eq ‘info@sample.com’)
Working with B2C can be difficult. The user interface is changing a lot and is always behind the normal Azure AD user interface. Using the graph api is helpfull in some situation. But how to get started? Hopefully this will help someone.
Accesstoken
First you need an accesstoken for the “old graph”. The Azure AD still works the best with the old Azure AD graph. Since Azure B2C is an implementation of the Azure AD, we are using that old graph.
First navigate to your B2C instance (do not go to Azure Active directory) in the Azure portal and create a new application with the app registration preview blade.
Create a new secret for the application under the menu item “Certificates & secrets”.
Copy the clientid (see Overview screen) and secret for later.
In this example we are going to use the accesstoken to manage users in Azure B2C. So we need permissions to do this. Add the permissions to the application. Make sure you add the permissions to the old Azure Active Directory graph!
Make sure you grant permissions and you selected application permissions (not delegated).
Postman
Open postman to generate a new accesstoken (for in example a Collection of requests) to manage B2C. We are using client credentials because we are managing B2C in name of the application.
You get the “Access Token URL” from here: https://login.microsoftonline.com/{{TenantId}}/oauth2/token
In this blog post I will explain how to apply the same validation rules on the same properties in different classes with FluentValidation. This post will continue on the previous one where I explained how to create Custom Validators for your properties.
So in the previous example we had the Person class with a PersonValidator class. Let’s say you have some pages in your application to create and edit instances of that Person class. In order to create those pages, we use separate ViewModels for those pages. So let’s say you have a PersonCreateViewModel and a PersonEditViewModel. In this way, you have 3 classes with the same validation rules, because in example the property FirstName is the same in all those classes. If the validation rules of the FirstName changes (in example the MaxLength changes) you have to change the rules on 3 different places. If you forget to change it on one place a new bug is introduced.
Reuse validators for property
In order to reuse the validators we are going to extend the static CustomValidators class from our previous post. Again we are creating an extension method but now for the FirstName property. We put all the validation rules that we have for this FirstName in this custom validator. The end result will than be the following:
We can now change the PersonValidator (and PersonCreateViewModel and PersonEditViewModel) to use the power of the new FirstNameValidation extension method. The end result will than be the following:
The PersonValidator class is now smaller and easier to read. The cool thing as well is that you can combine your custom FirstNameValidation extension method with your other extension methods as well. So when you have in example slightly different validation rules for your create and edit viewmodels you can use in example the FirstNameValidation method for the generic rules and add the specific rules in the particular validator class. See the following example where the edit viewmodel has extra validation rules:
Reusing validators saves you a lot of time and duplicate code. This will eventually result in less bugs. Nice is as well that your validator classes like the PersonValidator class is easier to read because it isn’t that long.
This blog post will explain how creating custom validators with FluentValidation. A while back I wrote a blog post about how to start with FluentValidation in your project. In this post we will continue on that foundation.
Let’s say in example you have the class Person.
C#
1
2
3
4
5
6
7
publicclassPerson
{
publicintId{get;set;}
publicstringFirstName{get;set;}
publicstringLastName{get;set;}
publicDateTimeBirthDay{get;set;}
}
You need to validate that Person class. So let’s say, you want to validate the FirstName and LastName property. Those properties are similar to each other because both are name and a string so both could have the same (custom) validators.
So let’s create a PersonValidator class which of course will validate the Person class.
Now, you want to extend the basic validators. So let’s say you want a validator that the name must not start with a whitespace. You can validate this on multiple ways but the most logical way is to create a custom validator once and use that validator on multiple places.
Here is the validator for checking whitespaces in the begin or end of a string.
Today, I continued working on my custom VSTS extension that I will publish in the near future. In the extension I needed a way how to use AzureAD PowerShell cmdlets on VSTS agent because it isn’t installed by default.
Ship cmdlets in extension
Installing AzureAD cmdlets is not really that difficult. You just download the AzureAD cmdlets module from the PowerShell gallery and put them in your extension so they will be installed with your extension.
Importing the cmdlets
After you put the cmdlets as artifact in your extension, you need to import them. You can do this in example in your execution PowerShell file (in my case Main.ps1) with the following code:
PowerShell
1
2
3
Write-Verbose"Import AzureAD module because is not on default VSTS agent"
After imported, you can use them. Of course you first need to login. Because we don’t want to hard code credentials in our extension, you will have to pass them to the Connect-AzureAD cmdlet. There are multiple ways on how to do this. Think in example of a credential file as variable. I used an Azure Resource Manager endpoint for this. I did this because I actually only wanted to use the AzureRM module for my extension but some of the cmdlets are only in the AzureAD module.
So how do we login? Connect-AzureAD doesn’t allow to login with a Service Principal and a key. You need to use a self-signed certificate for this what I don’t want. I already have an Azure Resource Manager endpoint with a key. I want to use that key so the login procedures for AzureRM and AzureAD are the same. I already wrote a post on how to login with a SP and key but with an existing Azure Resource Manager endpoint in your task you can use the following code:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Write-Verbose"Import AzureAD module because is not on default VSTS agent"
I needed this already multiple times but never got it working. Today, I needed again the ability to Connect to AzureAD with Service Principal because some actions can’t be done (yet) via the Azure Resource Manager.
You can’t login into the Azure AD with a key as a Service Principal. You need a certificate for this. Read for more information the documentation of Connect-AzureAD. In order to use a key for logging into the Azure AD, we need to login first into AzureRM because there it is possible by default. Then call something from the Azure AD (in example a group or application) with AzureRM so the tokencache of the AzureRM context is filled with a valid token to “https://graph.windows.net/”. After that, use the token to login with Connect-AzureAD AadAccessToken cmdlet.
Sample
This script (written in AzureRM 5.1.1 because VSTS hosted agents are using that as well) will get an Azure AD application via AzureRM and then via AzureAD cmdlets.
This is a small tutorial on how to upgrade PowershellGet to the latest version. The easiest way to upgrade your PowershellGet module is to run the following command:
PowerShell
1
Find-Modulepowershellget|Install-Module
After that, check your installed versions:
PowerShell
1
2
Get-Modulepowershellget-ListAvailable
Get-Modulepackagemanagement-ListAvailable
If you have multiple versions, the best thing todo is to remove the older versions. To remove the older versions, do the following:
Browse to C:\Program Files\WindowsPowerShell\Modules\
Go into C:\Program Files\WindowsPowerShell\Modules\PowershellGet folder, and delete the older version folders
Then do the same for C:\Program Files\WindowsPowerShell\Modules\PackageManagement
Now run the Get-Module commands again and see if the old versions are gone.
The result will be the ApplicationId, DisplayName, Id and Type. Copy the Id property (ObjectId) to add it as owner. You can also use the following shortcut: