How can I reference an existing certificate resource in bicep? - azure-keyvault

I have an existing certificate that in Key Vault that I would like to reference from my bicep template.
resource prodCertificate 'Microsoft.Web/certificates#2020-12-01' existing = {
name: 'my-custom-certificate-name/123809dsfj2jf09j32123123'
scope: resourceGroup('certificateResourceGroup')
}
The current bicep template will run in a different resource group, appServiceResourceGroup and the key vault is under the certificateResourceGroup
The above doesn't work because bicep complains that there should not be a slash in the name.
If I just use my-custom-certificate-name, I get an error that states
{
"code": "DeploymentFailed",
"message": "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.",
"details": [
{
"code": "ResourceNotFound",
"message": "The Resource 'Microsoft.Web/certificates/my-custom-certificate-name' under resource group 'certificateResourceGroup' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix"
}
]
}

I tested same scenario which you are trying i.e. import certificate from keyvault in a resource group to an App service present in another resource group.
I used the below code to do it :
param name string
param location string = resourceGroup().location
param keyvaultid string
param certificatesecretname string
#secure()
param pass string
param exisitingappplanresourceid string
resource prodCertificate 'Microsoft.Web/certificates#2021-02-01' = {
name: name
location: location
properties: {
keyVaultId: keyvaultid
keyVaultSecretName: certificatesecretname
password: pass
serverFarmId: exisitingappplanresourceid
}
}
Output:
Existing Certificate in Keyvault:
Deployments and parameters:
Azure portal App service:
Note: Please make sure to have Microsoft.Web Resource Provider to have access to the keyvault. You can do it from portal by going to Keyvault>>access policies>>add a accesspolicy and enter abfa0a7c-a6b6-4736-8310-5855508787cd in service principal search dialog box , so that it will add the the below resource provider to the access policy .
If you want to add the certificate from keyvault and then create a ssl binding as well then you can use something like below:
#description('Existing App Service Plan resource id that contains the App Service being updated')
param existingServerFarmId string
#description('User friendly certificate resource name')
param certificateName string
#description('Existing Key Vault resource Id with an access policy to allow Microsoft.Web RP to read Key Vault secrets (Checkout README.md for more information)')
param existingKeyVaultId string
#description('Key Vault Secret that contains a PFX certificate')
param existingKeyVaultSecretName string
#description('Existing App name to use for creating SSL binding. This App should have the hostname assigned as a custom domain')
param existingWebAppName string
#description('Custom hostname for creating SSL binding. This hostname should already be assigned to the Web App')
param hostname string
#description('Location for all resources.')
param location string = resourceGroup().location
resource certificateName_resource 'Microsoft.Web/certificates#2019-08-01' = {
name: certificateName
location: location
properties: {
keyVaultId: existingKeyVaultId
keyVaultSecretName: existingKeyVaultSecretName
serverFarmId: existingServerFarmId
}
}
resource existingWebAppName_resource 'Microsoft.Web/sites#2019-08-01' = {
name: existingWebAppName
location: location
properties: {
name: existingWebAppName
hostNameSslStates: [
{
name: hostname
sslState: 'SniEnabled'
thumbprint: certificateName_resource.properties.thumbprint
toUpdate: true
}
]
}
}
Reference:
Microsoft.Web/certificates - Bicep & ARM template reference | Microsoft Docs

Related

Where to find TemplateId while creating custom directory role MS Graph

I want to create custom directory role with specific permissions like:
microsoft.directory/users/create
microsoft.directory/users/delete
microsoft.directory/groups/create
microsoft.directory/groups/delete
microsoft.directory/applications/create
microsoft.directory/applications/delete
microsoft.directory/serviceprincipals/create
microsoft.directory/serviceprincipals/delete
I found how to automate this from MS graph:
POST https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions
Body
{
"description": "Can manage basic aspects of application registrations.",
"displayName": "Application Support Administrator",
"isEnabled": true,
"templateId": "<GUID>",
"rolePermissions": [
{
"allowedResourceActions": [
microsoft.directory/users/create
microsoft.directory/users/delete microsoft.directory/groups/create
microsoft.directory/groups/delete
microsoft.directory/applications/create
microsoft.directory/applications/delete
microsoft.directory/serviceprincipals/create
microsoft.directory/serviceprincipals/delete
]
}
]
}
What is template Id and how to get the value of this?
TIA
Note that, "templateId": "<GUID>" is an optional parameter and you can include it while creating multiple custom directory roles with common parameters.
To get the value of "templateId", you can create one GUID using this PowerShell command: (New-Guid).Guid
I tried to reproduce the same in my environment via Graph Explorer and got below results:
I ran the same query as you and created custom directory role from MS Graph like below:
POST https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions
{
"description": "Can manage basic aspects of application registrations.",
"displayName": "Application Support Administrator",
"isEnabled": true,
"templateId": "38837bf2-39d8-4c14-89f3-3e9c5e6c9b23", //GUID created from PowerShell
"rolePermissions": [
{
"allowedResourceActions": [
"microsoft.directory/users/create",
"microsoft.directory/users/delete",
"microsoft.directory/groups/create",
"microsoft.directory/groups/delete",
"microsoft.directory/applications/create",
"microsoft.directory/applications/delete",
"microsoft.directory/serviceprincipals/create",
"microsoft.directory/serviceprincipals/delete"
]
}
]
}
Response:
When I checked the same in Portal, I am able to find the new custom directory role like below:
To assign this role to user via Graph API, you can make use of below query:
POST https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments
{
"principalId":"<GUID OF USER>",
"roleDefinitionId":"<GUID OF ROLE DEFINITION>",
"directoryScopeId":"/<GUID OF APPLICATION REGISTRATION(ObjectID)>"
}
Response:
When I checked the same in Portal, role assigned to user successfully like below:

Outlook Oauth .default suffix error trying smtp and imap after getting token

Im trying to access an Outlook email using Oauth , Already set this permissions on Azure App:
So, using Oauth 2.0 client credentials grant I obtain the access Token:
But, when I try to authenticate with that token it fails, so I read that it was necessary to generate a second token call using that first one as a parameter and using imap and smtp scopes concatenated, and I tried like in the examples:
And as you see, I get this suffix error :
{
"error": "invalid_scope",
"error_description": "AADSTS1002012: The provided value for scope https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send
is not valid. Client credential flows must have a
scope value with /.default suffixed to the resource identifier (application ID URI).\r\nTrace ID: 41d2086b-f83e-41d8-b405-115249b27901\r\nCorrelation ID: 6afef855-3fc9-4259-864b-4ec8e293e9d0\r\nTimestamp: 2022-04-29 00:02:06Z",
"error_codes": [
1002012
],
"timestamp": "2022-04-29 00:02:06Z",
"trace_id": "41d2086b-f83e-41d8-b405-115249b27901",
"correlation_id": "6afef855-3fc9-4259-864b-4ec8e293e9d0"
}
Any idea what am I doing wrong ?, why the first token its not enough or how do I get the access one in the second call ?
Thanks in advance !!

unable to get given_name and family_name from azure v2 token endpoint

In the manifest of my application registration I've configured to retrieve the given_name and family_name claims (through the UI, the resulting manifest looks like this):
"idToken": [
{
"name": "family_name",
"source": "user",
"essential": false,
"additionalProperties": []
},
{
"name": "given_name",
"source": "user",
"essential": false,
"additionalProperties": []
}
],
During the redirect I add the profile scope along with the given_name and family_name scopes, which results in the following error.
Message contains error: 'invalid_client', error_description: 'AADSTS650053: The application 'REDACTED' asked for scope 'given_name' that doesn't exist on the resource '00000003-0000-0000-c000-000000000000'. Contact the app vendor.
Any ideas? As I understand that is what is required to configure these optional claims on the v2.0 endpoint as described here: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims#v20-specific-optional-claims-set
You should only use the profile 'scope', which should result in you receiving the given_name and family_name 'claims'. That's standard behaviour for an Authorization Server, which will then either:
Return the name details directly in the id token
Or allow you to send an access token to the user info endpoint to get the name details
However, Azure v2 is very Microsoft specific, and user info lookup can be painful and involve sending a separate type of token to the Graph user info endpoint. Hopefully you won't have to deal with that and you will get the name details directly in the id token.
I had a scenario where my API (which only received an access token) needed to get user info, and I solved it via steps 14 - 18 of this write up, but it's a convoluted solution.
Once you configure optional claims for your application through the UI or application manifest. you need to provide profile Delegated permissions for the application.

Change Azure AD B2C User Password with Graph API

I'm trying to use the Sample Graph API app to change a user's password but I'm getting:
Error Calling the Graph API Response:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
}
}
}
Graph API Request:
PATCH /mytenant.onmicrosoft.com/users/some-guid?api-version=1.6 HTTP/1.1
client-request-id: ffd564d3-d716-480f-a66c-07b02b0e32ab
date-time-utc: 2017.08.10 03:04 PM
JSON File
{
"passwordProfile": {
"password": "Somepassword1$",
"forceChangePasswordNextLogin": false
}
}
I've tested updating the user's displayName and that works fine.
{
"displayName": "Joe Consumer"
}
AD Application Permissions
I've configured my app permissions as described here.
Check out this article. Seems like it has the same symptoms.
Solution 1:
If you are receiving this error when you call the API that includes only read permissions, you have to set permissions in Azure Management Portal.
Go to Azure Management Portal and click Active Directory.
Select your custom AD directory.
Click Applications and select your Application.
Click CONFIGURE and scroll down to the section 'Permissions to other applications'.
Provide required Application Permissions and Delegated Permissions for Windows Azure Active Directory.
Finally save the changes.
Solution 2:
If you are receiving this error when you call the API that includes delete or reset password operations, that is because those operations require the Admin role of Company Administrator. As of now, you can only add this role via the Azure AD Powershell module.
Find the service principal using Get-MsolServicePrincipal –AppPrincipalId
Get-MsolServicePrincipal | ft DisplayName, AppPrincipalId -AutoSize
Use Add-MsolRoleMember to add it to Company Administrator role
$clientIdApp = 'your-app-id'
$webApp = Get-MsolServicePrincipal –AppPrincipalId $clientIdApp
Add-MsolRoleMember -RoleName "Company Administrator" -RoleMemberType ServicePrincipal -RoleMemberObjectId $webApp.ObjectId
To connect to your B2C tenant via PowerShell you will need a local admin account. This blog post should help with that, see "The Solution" section.
Try below settings, works for me.
Used the below JSON
{
"accountEnabled": true,
"signInNames": [
{
"type": "emailAddress",
"value": "kart.kala1#test.com"
}
],
"creationType": "LocalAccount",
"displayName": "Joe Consumer",
"mailNickname": "joec",
"passwordProfile": {
"password": "P#$$word!",
"forceChangePasswordNextLogin": false
},
"passwordPolicies": "DisablePasswordExpiration",
"givenName": "Joe",
}
Also make sure you assign the application the user account, administrator role which will allow it to delete users link here

Swagger - Adding multiple security parameters to the same schema definition

Aim
To include multiple security headers to every request made within the API
Problem
I am trying to add multiple headers to my Swagger YAML security definitions.
I have trawled though the API but not have alot of luck
But am finding that when making the 'Try-This-Operation' I am required to select one. Rather than able to use both. Is this correct or am I doing something incorrectly?
Snippet
securityDefinitions:
userEmail:
type: apiKey
name: User Email
in: header
clientId:
type: apiKey
name: Client Id
in: header
security: [ { userEmail: [], clientId: [] } ]
Alternative?
If I am trying to do this impossible ...
Is it possible to specify these parameters as default for all the rest paths within the swagger document?
I am new to Swagger this week any have found everything else without problem ... but I cannot find any good example of this.
If any guidance could be given that would be incredibly helpful
Many thanks
Your SecurityDefintions object looks ok. Beware that
security: [ { userEmail: [], clientId: [] } ]
means the API client MUST use userEmail authentication AND clientId authentication at once! You probably meant:
security: [ { userEmail: [] }, { clientId: [] } ]
which means the API client MUST use either userEmail authentication OR clientId authentication.
To avoid repeating this definition over and over again you can use the global security property that applies to all paths without their own security object:
security: [ { userEmail: [] }, { clientId: [] } ]
paths:
"/foo":
get:
post:
or make use of a reference for explicitness or for multiple common values:
paths:
"/foo":
get:
security:
"$ref": "#/definitions/lowSecurity"
post:
security:
"$ref": "#/definitions/highSecurity"
definitions:
lowSecurity: [ { foo: [] }, { bar: [] } ]
highSecurity: [ { foo: [] } ]
Reference
The Swagger2 specification states under Operation Object:
security:
[Security Requirement Object]
A declaration of which security schemes are applied for this operation. The list of values describes alternative security schemes that can be used (that is, there is a logical OR between the security requirements). This definition overrides any declared top-level security. To remove a top-level security declaration, an empty array can be used.
The Security Requirement Object is described like this:
Lists the required security schemes to execute this operation. The object can have multiple security schemes declared in it which are all required (that is, there is a logical AND between the schemes).
The name used for each property MUST correspond to a security scheme declared in the Security Definitions.
OAS 3: https://swagger.io/docs/specification/authentication/
Using Multiple Authentication Types
Some REST APIs support several authentication types. The security section lets you combine the security requirements using logical OR and AND to achieve the desired result. security uses the following logic:
security: # A OR B
- A
- B
security: # A AND B
- A
B
security: # (A AND B) OR (C AND D)
- A
B
- C
D

Resources