How to protect Azure Function Endpoints with custom roles and permission? - azure

I need a starting point to solve the following problem:
Assume there is a model with different entities (e.g. school classes) and different roles that are connected to entities.
Now I want to check in my Azure Function if Bob has a role on this entity which entitles him to rate a student from the school class.
I think of a claim of the form:
TEACHER : [
"class 2b"
]
before.
Which Azure Resources do I need to map such a thing?
I already use Azure AZ for the ID token and my API is implemented in an Azure Function.
I would like to call Azure AD to get an access token which contains those roles and resources of my domain.

I'm afraid that this form is not supported by Azure AD.
The supported form should be "{claim name}": "{claim value}".
If you accept this form, you can refer to my previous answer.
What you need to modify is:
When you create the extensionProperty, you should name the extensionProperty as "TEACHER".
Post https://graph.microsoft.com/v1.0/applications/{object id of the Azure AD application}/extensionProperties
{"name":"TEACHER","dataType":"string","targetObjects":["User"]}
And update the extension property for your account:
Patch https://graph.microsoft.com/v1.0/me
{"extension_6d8190fbf1fe4bc38a5a145520221989_TEACHER":"class 2b"}
Then you can get the custom claim as "TEACHER": "class 2b".

Related

Generate Display Name with Azure function and API connector Azure B2C

I'm using the azure b2c sign-up policy(built-in policy) in my application. I am getting the first name and last name from the user during sign-up. Since I am not taking display name, so display name is getting saved as unknown.
I am thinking of creating an azure function that will update the display name as firstname_lastname and link it to user flow as an API connector. Can you please let me know if you have tried the same. It will be great if I can get a sample azure function code for the same.
You can definitely do this in a custom policy.
However, for the API connector, the docs say that the claim returned "overrides any value that has already been provided by a user in the attribute collection page". You haven't provided "displayName" so this may not be possible.
There are some function quick starts here.
In your case, the claims names in the API are:
"displayName" = "givenName" + " " + "surname"

Azure AD SCIM 2.0 roles and appRoleAssignments empty

In Azure AD I setup SCIM which is working great. However for some reason roles as well as appRoleAssignments are never sent in the body of a SCIM POST or PATCH request.
As an example, here's the SCIM body for a POST request:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"userName":"testBlaBla#example.com",
"active":true,
"displayName":"Test Bla bla",
"meta": {
"resourceType":"User"
},
"roles":[]
}
This test user has been assigned with Directory Roles and Application Roles. An attribute (with default value "n/a") for the appRoleAssignments was added and mapped. And API permissions for read/write Application Role Assignments was added.
Screenshot of SCIM Attribute mappings with target application
Screenshot of custom added appRoleAssignments attribute
How can I get SCIM in Azure AD to also sent Roles and Application Roles information to the target application?
Ensure that you are using a mapping of type expression rather than direct and user the appRoleassignment function.
https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/customize-application-attributes#provisioning-a-role-to-a-scim-app
Select the target attribute that comes out of the box or if you extend the schema follow the format described here, e.g.:
urn:ietf:params:scim:schemas:extension:2.0:CustomExtensionName:appRoles
or
urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User.appRoles:value
https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/customize-application-attributes#provisioning-a-custom-extension-attribute-to-a-scim-compliant-application

Azure REST API get resource parentResourcePath parameter

Context
I am willing to get a resource details with the Azure REST API. And more particularly, I want to get the IAM associated with a resource.
Problem
So, I searched in the doc reference and found that endpoint: https://learn.microsoft.com/en-us/rest/api/resources/resources/get which provides an identity response attribute that meets my needs.
However, I can't find any information about the required path parameter parentResourcePath. What does that parameter mean and how can I get its value for a specific resource ?
Also, when I tried going through the resources group path, I can get a path to the resource details but without the parentResourcePath parameter, and the response doesn't include the identity attribute.
Finally, am I going the right way (using GET resource API) ? And if so, where can I find that parentResourcePath value ?
Actually, you have a better choice - Resources - Get By Id.
The /subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName} in the api Resources - Get named resourceId which used in the Resources - Get By Id.
But if you combinate the properties manually, it is not easy, Azure has many different resource providers, resourcetype.
Generally, you could find the resourceId in your resource in the portal -> Properties. Also, the response of this API will include the identity which you need.
Sample:
Get a web app resource.
The resourceId is like /subscriptions/xxxxxxx/resourceGroups/joywebapp/providers/Microsoft.Web/sites/joywebapp2.
You can click Try it in the doc to try the api.
Response:
Well I made it throught the Role assignment list for scope endpoint, giving the subscription/resourcegroup/resource in the scope. And the output contains a principalId attribute that seems to point to a user or group or service principal.
Ref: https://learn.microsoft.com/en-us/rest/api/authorization/roleassignments/listforscope

Getting all B2B directories user is member of

Since we have Azure AD's B2B feature in GA, I am curious how to make use of B2B in multi-tenant applications. More specifically, how to get a list of directories which the user is member of? For example, the Azure Portal does this by calling https://portal.azure.com/AzureHubs/api/tenants/List, Microsoft's My Apps calls https://account.activedirectory.windowsazure.com/responsive/multidirectoryinfo to get the information - is there a public endpoint for this?
The use case is to enable B2B cooperation across a multi-tenant application which is provisioned in each user's directory so they have their own instances, but there is no way to centrally pull the information about user's directories.
A simple workaround would be to query all tenants which have the application provisioned for the user's UPN and if found, display it in the list, but imagine if there were hundreds of tenants... I believe that this is quite crucial for app developers who want to leverage the B2B functions in multi-tenant applications.
Update: It seems like there is a way to do this by accessing the Azure Service Management API, however this API and method is undocumented and I suppose that if any issues would occur, Microsoft would say that it is not a supported scenario.
Update 2: I wrote an article about the whole setup, including a sample project of how to make use of this in a scenario, it can be found here https://hajekj.net/2017/07/24/creating-a-multi-tenant-application-which-supports-b2b-users/
There is a publicly documented Azure Management API that allows you to do this: https://learn.microsoft.com/en-us/rest/api/resources/tenants
GET https://management.azure.com/tenants?api-version=2016-06-01 HTTP/1.1
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUz...
...
The response body looks something like this:
{
"value" : [{
"id" : "/tenants/d765d508-7139-4851-b9c5-74d6dbb1edf0",
"tenantId" : "d765d508-7139-4851-b9c5-74d6dbb1edf0"
}, {
"id" : "/tenants/845415f3-7a05-45c2-8376-ee67080661e2",
"tenantId" : "845415f3-7a05-45c2-8376-ee67080661e2"
}, {
"id" : "/tenants/97bcb93f-8dee-48ed-afa3-356ba40f3a61",
"tenantId" : "97bcb93f-8dee-48ed-afa3-356ba40f3a61"
}
]
}
The resource for which you need to acquire an access token is https://management.azure.com/ (with the trailing slash!).

New-AzureRmRoleAssignment programmatically in a .NET Core console application

It seems I'm on a journey to first programmatically create an Azure application and then use Azure Management APIs to do create some resource. There's a new snag I'd like to ask from the community, how to do basically the PowerShell command New-AzureRmRoleAssignment -RoleDefinitionName Owner -ServicePrincipalName $adApp.ApplicationId.Guid using HttpClient (or some smarter method with the exact needed permissions using Microsoft Graph API libraries).
Trying to be a better person this time (being more around, providing code), I prepared a repo in GH, but the issue basically boils down to what kind of a URI should be used (here). The code is
var roleAssignment = $"{{something here}}";
var roleAssignementContent = new StringContent(roleAssignment, Encoding.UTF8, "application/json");
var roleAssignmentResponse = await client.PostAsync($"https://graph.windows.net/{tenants.value[0].tenantId}/applications/{createdApplication.appId}?api-version=1.6", roleAssignementContent).ConfigureAwait(false);
var roleAssignement = await roleAssignmentResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
I fiddled with Graph API Explorer too if things were easier using it (or the libraries) but with less luck. Indeed, the ultimate goal is to create application programmatically so that it becomes possible to use Azure Management Libraries to make a deployment. That is, all in code from the beginning to an end.
(Also, the code is of throwaway quality, to provide a more functioning example only.)
New-AzureRmRoleAssignment is used to assign the specified RBAC role to the specified service principal , you could achieve that by using the Resource Manager create role assignment API:
Get ObjectId of application service principal.
if you have got the objectId of application service principal before , you could skip this step .If not , you could use Azure ad graph api to request an application's service principal by application id :
GET https://graph.windows.net/<TenantID>/servicePrincipals?$filter=servicePrincipalNames/any(c:%20c%20eq%20'applicationID')&api-version=1.6
Authorization: Bearer eyJ0eXAiOiJK*****-kKorR-pg
Get Azure RBAC role identifier
To assign the appropriate RBAC role to your service principal, you must know the identifier of the Azure RBAC role(Owner in your scenario), you could call the Resource Manager role definition API to list all Azure RBAC roles and search then iterate over the result to find the desired role definition by name.:
GET https://management.azure.com/subscriptions/ed0caab7-c6d4-45e9-9289-c7e5997c9241/providers/Microsoft.Authorization/roleDefinitions?$filter=roleName%20eq%20'Owner'&api-version=2015-07-01
Authorization: Bearer
Assign the appropriate RBAC role to service principal:
PUT https://management.azure.com/subscriptions/ed0caab7-c6d4-45e9-9289-c7e5997c9241/providers/Microsoft.Authorization/roleAssignments/16fca587-013e-45f2-a03c-cfc9899a6ced?api-version=2015-07-01
Authorization: Bearer eyJ0eXAiOiJKV1QiL*****FlwO1mM7Cw6JWtfY2lGc5
Content-Type: application/json
{
"properties": {
"roleDefinitionId": "/subscriptions/XXXXXXXXXXXXXXX/providers/Microsoft.Authorization/roleDefinitions/XXXXXXXXXXXXXXXXX",
"principalId": "XXXXXXXXXXXXXXXXXXXXX"
}
}
roleDefinitionId is the id you get in step 2 ,principalId is the objectId you get in step 1 . ed0caab7-c6d4-45e9-9289-c7e5997c9241 is the subscription id ,16fca587-013e-45f2-a03c-cfc9899a6ced is a new guid created for the new role assignment .
Please refer to below document for more details :
Use Resource Manager authentication API to access subscriptions

Resources