Skip to content

Commit 68adc9b

Browse files
authored
Merge pull request #247728 from MicrosoftDocs/repo_sync_working_branch
Confirm merge from repo_sync_working_branch to main to sync with https://github.com/MicrosoftDocs/azure-docs (branch main)
2 parents 5be21d2 + 2d84d00 commit 68adc9b

22 files changed

+454
-119
lines changed

articles/active-directory/authentication/concept-system-preferred-multifactor-authentication.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ms.collection: M365-identity-device-management
1414

1515
# Customer intent: As an identity administrator, I want to encourage users to use the Microsoft Authenticator app in Azure AD to improve and secure user sign-in events.
1616
---
17+
1718
# System-preferred multifactor authentication - Authentication methods policy
1819

1920
System-preferred multifactor authentication (MFA) prompts users to sign in by using the most secure method they registered. Administrators can enable system-preferred MFA to improve sign-in security and discourage less secure sign-in methods like SMS.
@@ -111,7 +112,7 @@ When a user signs in, the authentication process checks which authentication met
111112

112113
1. [Temporary Access Pass](howto-authentication-temporary-access-pass.md)
113114
1. [FIDO2 security key](concept-authentication-passwordless.md#fido2-security-keys)
114-
1. [Microsoft Authenticator push notifications](concept-authentication-authenticator-app.md)
115+
1. [Microsoft Authenticator notifications](concept-authentication-authenticator-app.md)
115116
1. [Time-based one-time password (TOTP)](concept-authentication-oath-tokens.md)<sup>1</sup>
116117
1. [Telephony](concept-authentication-phone-options.md)<sup>2</sup>
117118
1. [Certificate-based authentication](concept-certificate-based-authentication.md)
@@ -134,3 +135,5 @@ The system-preferred MFA also applies for users who are enabled for MFA in the l
134135

135136
* [Authentication methods in Azure Active Directory](concept-authentication-authenticator-app.md)
136137
* [How to run a registration campaign to set up Microsoft Authenticator](how-to-mfa-registration-campaign.md)
138+
139+

articles/active-directory/develop/jwt-claims-customization.md

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,288 @@ As another example, consider when Britta Simon tries to sign in using the follow
195195

196196
As a final example, consider what happens if Britta has no `user.othermail` configured or it's empty. The claim falls back to `user.extensionattribute1` ignoring the condition entry in both cases.
197197

198+
## Security considerations
199+
Applications that receive tokens rely on claim values that are authoritatively issued by Azure AD and can't be tampered with. When you modify the token contents through claims customization, these assumptions may no longer be correct. Applications must explicitly acknowledge that tokens have been modified by the creator of the customization to protect themselves from customizations created by malicious actors. This can be done in one the following ways:
200+
201+
- [Configure a custom signing key](#configure-a-custom-signing-key)
202+
- [update the application manifest to accept mapped claims](#update-the-application-manifest).
203+
204+
Without this, Azure AD returns an [AADSTS50146 error code](reference-aadsts-error-codes.md#aadsts-error-codes).
205+
206+
## Configure a custom signing key
207+
For multi-tenant apps, a custom signing key should be used. Don't set `acceptMappedClaims` in the app manifest. when setting up an app in the Azure portal, you get an app registration object and a service principal in your tenant. That app is using the Azure global sign-in key, which can't be used for customizing claims in tokens. To get custom claims in tokens, create a custom sign-in key from a certificate and add it to service principal. For testing purposes, you can use a self-signed certificate. After configuring the custom signing key, your application code needs to validate the token signing key.
208+
209+
Add the following information to the service principal:
210+
211+
- Private key (as a [key credential](/graph/api/resources/keycredential?view=graph-rest-1.0&preserve-view=true))
212+
- Password (as a [password credential](/graph/api/resources/passwordcredential?view=graph-rest-1.0&preserve-view=true))
213+
- Public key (as a [key credential](/graph/api/resources/keycredential?view=graph-rest-1.0&preserve-view=true))
214+
215+
Extract the private and public key base-64 encoded from the PFX file export of your certificate. Make sure that the `keyId` for the `keyCredential` used for "Sign" matches the `keyId` of the `passwordCredential`. You can generate the `customkeyIdentifier` by getting the hash of the cert's thumbprint.
216+
217+
## Request
218+
The following example shows the format of the HTTP PATCH request to add a custom signing key to a service principal. The "key" value in the `keyCredentials` property is shortened for readability. The value is base-64 encoded. For the private key, the property usage is "Sign". For the public key, the property usage is "Verify".
219+
220+
```
221+
PATCH https://graph.microsoft.com/v1.0/servicePrincipals/f47a6776-bca7-4f2e-bc6c-eec59d058e3e
222+
223+
Content-type: servicePrincipals/json
224+
Authorization: Bearer {token}
225+
226+
{
227+
"keyCredentials":[
228+
{
229+
"customKeyIdentifier": "lY85bR8r6yWTW6jnciNEONwlVhDyiQjdVLgPDnkI5mA=",
230+
"endDateTime": "2021-04-22T22:10:13Z",
231+
"keyId": "4c266507-3e74-4b91-aeba-18a25b450f6e",
232+
"startDateTime": "2020-04-22T21:50:13Z",
233+
"type": "X509CertAndPassword",
234+
"usage": "Sign",
235+
"key":"MIIKIAIBAz.....HBgUrDgMCERE20nuTptI9MEFCh2Ih2jaaLZBZGeZBRFVNXeZmAAgIH0A==",
236+
"displayName": "CN=contoso"
237+
},
238+
{
239+
"customKeyIdentifier": "lY85bR8r6yWTW6jnciNEONwlVhDyiQjdVLgPDnkI5mA=",
240+
"endDateTime": "2021-04-22T22:10:13Z",
241+
"keyId": "e35a7d11-fef0-49ad-9f3e-aacbe0a42c42",
242+
"startDateTime": "2020-04-22T21:50:13Z",
243+
"type": "AsymmetricX509Cert",
244+
"usage": "Verify",
245+
"key": "MIIDJzCCAg+gAw......CTxQvJ/zN3bafeesMSueR83hlCSyg==",
246+
"displayName": "CN=contoso"
247+
}
248+
249+
],
250+
"passwordCredentials": [
251+
{
252+
"customKeyIdentifier": "lY85bR8r6yWTW6jnciNEONwlVhDyiQjdVLgPDnkI5mA=",
253+
"keyId": "4c266507-3e74-4b91-aeba-18a25b450f6e",
254+
"endDateTime": "2022-01-27T19:40:33Z",
255+
"startDateTime": "2020-04-20T19:40:33Z",
256+
"secretText": "mypassword"
257+
}
258+
]
259+
}
260+
```
261+
262+
## Configure a custom signing key using PowerShell
263+
Use PowerShell to [instantiate an MSAL Public Client Application](msal-net-initializing-client-applications.md#initializing-a-public-client-application-from-code) and use the [Authorization Code Grant](v2-oauth2-auth-code-flow.md) flow to obtain a delegated permission access token for Microsoft Graph. Use the access token to call Microsoft Graph and configure a custom signing key for the service principal. After configuring the custom signing key, your application code needs to [validate the token signing key](#validate-token-signing-key).
264+
265+
To run this script you need:
266+
267+
- The object ID of your application's service principal, found in the Overview blade of your application's entry in Enterprise Applications in the Azure portal.
268+
- An app registration to sign in a user and get an access token to call Microsoft Graph. Get the application (client) ID of this app in the Overview blade of the application's entry in App registrations in the Azure portal. The app registration should have the following configuration:
269+
- A redirect URI of "http://localhost" listed in the **Mobile and desktop applications** platform configuration.
270+
- In **API permissions**, Microsoft Graph delegated permissions **Application.ReadWrite.All** and **User.Read** (make sure you grant Admin consent to these permissions).
271+
- A user who logs in to get the Microsoft Graph access token. The user should be one of the following Azure AD administrative roles (required to update the service principal):
272+
- Cloud Application Administrator
273+
- Application Administrator
274+
- Global Administrator
275+
- A certificate to configure as a custom signing key for our application. You can either create a self-signed certificate or obtain one from your trusted certificate authority. The following certificate components are used in the script:
276+
- public key (typically a .cer file)
277+
- private key in PKCS#12 format (in .pfx file)
278+
- password for the private key (pfx file)
279+
280+
> [!IMPORTANT]
281+
> The private key must be in PKCS#12 format since Azure AD doesn't support other format types. Using the wrong format can result in the error "Invalid certificate: Key value is invalid certificate" when using Microsoft Graph to PATCH the service principal with a `keyCredentials` containing the certificate information.
282+
283+
```
284+
$fqdn="fourthcoffeetest.onmicrosoft.com" # this is used for the 'issued to' and 'issued by' field of the certificate
285+
$pwd="mypassword" # password for exporting the certificate private key
286+
$location="C:\\temp" # path to folder where both the pfx and cer file will be written to
287+
288+
# Create a self-signed cert
289+
$cert = New-SelfSignedCertificate -certstorelocation cert:\currentuser\my -DnsName $fqdn
290+
$pwdSecure = ConvertTo-SecureString -String $pwd -Force -AsPlainText
291+
$path = 'cert:\currentuser\my\' + $cert.Thumbprint
292+
$cerFile = $location + "\\" + $fqdn + ".cer"
293+
$pfxFile = $location + "\\" + $fqdn + ".pfx"
294+
295+
# Export the public and private keys
296+
Export-PfxCertificate -cert $path -FilePath $pfxFile -Password $pwdSecure
297+
Export-Certificate -cert $path -FilePath $cerFile
298+
299+
$ClientID = "<app-id>"
300+
$loginURL = "https://login.microsoftonline.com"
301+
$tenantdomain = "fourthcoffeetest.onmicrosoft.com"
302+
$redirectURL = "http://localhost" # this reply URL is needed for PowerShell Core
303+
[string[]] $Scopes = "https://graph.microsoft.com/.default"
304+
$pfxpath = $pfxFile # path to pfx file
305+
$cerpath = $cerFile # path to cer file
306+
$SPOID = "<service-principal-id>"
307+
$graphuri = "https://graph.microsoft.com/v1.0/serviceprincipals/$SPOID"
308+
$password = $pwd # password for the pfx file
309+
310+
311+
# choose the correct folder name for MSAL based on PowerShell version 5.1 (.Net) or PowerShell Core (.Net Core)
312+
313+
if ($PSVersionTable.PSVersion.Major -gt 5)
314+
{
315+
$core = $true
316+
$foldername = "netcoreapp2.1"
317+
}
318+
else
319+
{
320+
$core = $false
321+
$foldername = "net45"
322+
}
323+
324+
# Load the MSAL/microsoft.identity/client assembly -- needed once per PowerShell session
325+
[System.Reflection.Assembly]::LoadFrom((Get-ChildItem C:/Users/<username>/.nuget/packages/microsoft.identity.client/4.32.1/lib/$foldername/Microsoft.Identity.Client.dll).fullname) | out-null
326+
327+
$global:app = $null
328+
329+
$ClientApplicationBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($ClientID)
330+
[void]$ClientApplicationBuilder.WithAuthority($("$loginURL/$tenantdomain"))
331+
[void]$ClientApplicationBuilder.WithRedirectUri($redirectURL)
332+
333+
$global:app = $ClientApplicationBuilder.Build()
334+
335+
Function Get-GraphAccessTokenFromMSAL {
336+
[Microsoft.Identity.Client.AuthenticationResult] $authResult = $null
337+
$AquireTokenParameters = $global:app.AcquireTokenInteractive($Scopes)
338+
[IntPtr] $ParentWindow = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle
339+
if ($ParentWindow)
340+
{
341+
[void]$AquireTokenParameters.WithParentActivityOrWindow($ParentWindow)
342+
}
343+
try {
344+
$authResult = $AquireTokenParameters.ExecuteAsync().GetAwaiter().GetResult()
345+
}
346+
catch {
347+
$ErrorMessage = $_.Exception.Message
348+
Write-Host $ErrorMessage
349+
}
350+
351+
return $authResult
352+
}
353+
354+
$myvar = Get-GraphAccessTokenFromMSAL
355+
if ($myvar)
356+
{
357+
$GraphAccessToken = $myvar.AccessToken
358+
Write-Host "Access Token: " $myvar.AccessToken
359+
#$GraphAccessToken = "eyJ0eXAiOiJKV1QiL ... iPxstltKQ"
360+
361+
362+
# this is for PowerShell Core
363+
$Secure_String_Pwd = ConvertTo-SecureString $password -AsPlainText -Force
364+
365+
# reading certificate files and creating Certificate Object
366+
if ($core)
367+
{
368+
$pfx_cert = get-content $pfxpath -AsByteStream -Raw
369+
$cer_cert = get-content $cerpath -AsByteStream -Raw
370+
$cert = Get-PfxCertificate -FilePath $pfxpath -Password $Secure_String_Pwd
371+
}
372+
else
373+
{
374+
$pfx_cert = get-content $pfxpath -Encoding Byte
375+
$cer_cert = get-content $cerpath -Encoding Byte
376+
# Write-Host "Enter password for the pfx file..."
377+
# calling Get-PfxCertificate in PowerShell 5.1 prompts for password
378+
# $cert = Get-PfxCertificate -FilePath $pfxpath
379+
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($pfxpath, $password)
380+
}
381+
382+
# base 64 encode the private key and public key
383+
$base64pfx = [System.Convert]::ToBase64String($pfx_cert)
384+
$base64cer = [System.Convert]::ToBase64String($cer_cert)
385+
386+
# getting id for the keyCredential object
387+
$guid1 = New-Guid
388+
$guid2 = New-Guid
389+
390+
# get the custom key identifier from the certificate thumbprint:
391+
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256')
392+
$hash = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($cert.Thumbprint))
393+
$customKeyIdentifier = [System.Convert]::ToBase64String($hash)
394+
395+
# get end date and start date for our keycredentials
396+
$endDateTime = ($cert.NotAfter).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
397+
$startDateTime = ($cert.NotBefore).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
398+
399+
# building our json payload
400+
$object = [ordered]@{
401+
keyCredentials = @(
402+
[ordered]@{
403+
customKeyIdentifier = $customKeyIdentifier
404+
endDateTime = $endDateTime
405+
keyId = $guid1
406+
startDateTime = $startDateTime
407+
type = "X509CertAndPassword"
408+
usage = "Sign"
409+
key = $base64pfx
410+
displayName = "CN=fourthcoffeetest"
411+
},
412+
[ordered]@{
413+
customKeyIdentifier = $customKeyIdentifier
414+
endDateTime = $endDateTime
415+
keyId = $guid2
416+
startDateTime = $startDateTime
417+
type = "AsymmetricX509Cert"
418+
usage = "Verify"
419+
key = $base64cer
420+
displayName = "CN=fourthcoffeetest"
421+
}
422+
)
423+
passwordCredentials = @(
424+
[ordered]@{
425+
customKeyIdentifier = $customKeyIdentifier
426+
keyId = $guid1
427+
endDateTime = $endDateTime
428+
startDateTime = $startDateTime
429+
secretText = $password
430+
}
431+
)
432+
}
433+
434+
$json = $object | ConvertTo-Json -Depth 99
435+
Write-Host "JSON Payload:"
436+
Write-Output $json
437+
438+
# Request Header
439+
$Header = @{}
440+
$Header.Add("Authorization","Bearer $($GraphAccessToken)")
441+
$Header.Add("Content-Type","application/json")
442+
443+
try
444+
{
445+
Invoke-RestMethod -Uri $graphuri -Method "PATCH" -Headers $Header -Body $json
446+
}
447+
catch
448+
{
449+
# Dig into the exception to get the Response details.
450+
# Note that value__ is not a typo.
451+
Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
452+
Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
453+
}
454+
455+
Write-Host "Complete Request"
456+
}
457+
else
458+
{
459+
Write-Host "Fail to get Access Token"
460+
}
461+
```
462+
463+
## Validate token signing key
464+
Apps that have claims mapping enabled must validate their token signing keys by appending `appid={client_id}` to their [OpenID Connect metadata requests](v2-protocols-oidc.md#fetch-the-openid-configuration-document). The following example shows the format of the OpenID Connect metadata document you should use:
465+
466+
```
467+
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?appid={client-id}
468+
```
469+
470+
## Update the application manifest
471+
For single tenant apps, you can set the `acceptMappedClaims` property to `true` in the [application manifest](reference-app-manifest.md). As documented on the [apiApplication resource type](/graph/api/resources/apiapplication?view=graph-rest-1.0&preserve-view=true#properties), this allows an application to use claims mapping without specifying a custom signing key.
472+
473+
>[!WARNING]
474+
>Do not set the acceptMappedClaims property to true for multi-tenant apps, which can allow malicious actors to create claims-mapping policies for your app.
475+
476+
The requested token audience is required to use a verified domain name of your Azure AD tenant, which means you should set the `Application ID URI` (represented by the `identifierUris` in the application manifest) for example to `https://contoso.com/my-api` or (simply using the default tenant name) `https://contoso.onmicrosoft.com/my-api`.
477+
478+
If you're not using a verified domain, Azure AD returns an `AADSTS501461` error code with message "_AcceptMappedClaims is only supported for a token audience matching the application GUID or an audience within the tenant's verified domains. Either change the resource identifier or use an application-specific signing key."
479+
198480
## Advanced claims options
199481

200482
Configure advanced claims options for OIDC applications to expose the same claim as SAML tokens. Also for applications that intend to use the same claim for both SAML2.0 and OIDC response tokens.

articles/api-management/virtual-network-concepts.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ The minimum size of the subnet in which API Management can be deployed is /29, w
107107

108108
* **/25 subnet**: 128 possible IP addresses - 5 reserved Azure IP addresses - 2 API Management IP addresses for one instance - 1 IP address for internal load balancer, if used in internal mode = 120 remaining IP addresses left for sixty scale-out units (2 IP addresses/scale-out unit) for a total of sixty-one units. This is an extremely large, theoretical number of scale-out units.
109109

110+
> [!IMPORTANT]
111+
> The private IP addresses of internal load balancer and API Management units are assigned dynamically. Therefore, it is impossible to anticipate the private IP of the API Management instance prior to its deployment. Additionally, changing to a different subnet and then returning may cause a change in the private IP address.
112+
110113
### Routing
111114

112115
See the Routing guidance when deploying your API Management instance into an [external VNet](./api-management-using-with-vnet.md#routing) or [internal VNet](./api-management-using-with-internal-vnet.md#routing).

articles/azure-app-configuration/faq.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ sections:
130130
131131
Check the body of the 429 response for the specific reason why the request failed.
132132
133-
†A configuration store may experience momentary throttling if it receives a large burst of requests or transfers an excessive volume of data. App Configuration clients, such as the Azure SDK, configuration provider libraries, and Azure Pipeline tasks, automatically retry on throttled requests. For any applications using one of these clients, or a custom client that retries on throttled requests, this momentary throttling should go unnoticed, should it occur.
133+
†A configuration store may experience momentary throttling if it receives a large burst of requests or transfers an excessive volume of data. App Configuration clients, such as the Azure SDK, configuration provider libraries, and Azure Pipelines tasks, automatically retry on throttled requests. For any applications using one of these clients, or a custom client that retries on throttled requests, this momentary throttling should go unnoticed, should it occur.
134134
135135
- question: How do I estimate the number of requests my application may send to App Configuration?
136136
answer: |

articles/azure-large-instances/find-your-subscription-id.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,10 @@ ms.date: 06/01/2023
1414
This article explains how to find your Azure Large Instances subscription ID.
1515

1616
A *Subscription ID* is a unique identifier for your service in Azure.
17-
You need it when interacting with the Microsoft Support team. To find your subscription ID, follow these steps:
17+
You need it when interacting with the Microsoft Support team.
18+
To find your subscription ID, follow these steps:
1819

1920
1. Go to [Azure support portal](https://portal.Azure.Com)
20-
2. From the left pane, select **Subscriptions**.
21-
3. A new blade called “Subscriptions” will open to display your subscriptions.
22-
23-
1. Choose the subscription you have used for Azure Large Instances.
24-
25-
26-
27-
21+
2. In **Azure services**, select **Subscriptions**.
22+
The **Subscriptions** blade appears, displaying your subscriptions.
23+
3. Choose the subscription you have used for Azure Large Instances.

0 commit comments

Comments
 (0)