Skip to content

Commit d02c854

Browse files
committed
Merge branch 'main' of https://github.com/MicrosoftDocs/azure-docs-pr into github-3
2 parents 7dfc8e7 + 598f074 commit d02c854

37 files changed

+664
-441
lines changed

articles/active-directory/external-identities/code-samples.md

Lines changed: 113 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ services: active-directory
66
ms.service: active-directory
77
ms.subservice: B2B
88
ms.topic: sample
9-
ms.date: 04/11/2017
9+
ms.date: 03/14/2022
1010

1111
ms.author: mimart
1212
author: msmimart
@@ -19,7 +19,8 @@ ms.collection: M365-identity-device-management
1919
# Azure Active Directory B2B collaboration code and PowerShell samples
2020

2121
## PowerShell example
22-
You can bulk-invite external users to an organization from email addresses that you have stored in a .CSV file.
22+
23+
You can bulk-invite external users to an organization from email addresses that you've stored in a .CSV file.
2324

2425
1. Prepare the .CSV file
2526
Create a new CSV file and name it invitations.csv. In this example, the file is saved in C:\data, and contains the following information:
@@ -49,49 +50,49 @@ You can bulk-invite external users to an organization from email addresses that
4950
foreach ($email in $invitations) {New-AzureADMSInvitation -InvitedUserEmailAddress $email.InvitedUserEmailAddress -InvitedUserDisplayName $email.Name -InviteRedirectUrl https://wingtiptoysonline-dev-ed.my.salesforce.com -InvitedUserMessageInfo $messageInfo -SendInvitationMessage $true}
5051
```
5152

52-
This cmdlet sends an invitation to the email addresses in invitations.csv. Additional features of this cmdlet include:
53+
This cmdlet sends an invitation to the email addresses in invitations.csv. More features of this cmdlet include:
54+
5355
- Customized text in the email message
5456
- Including a display name for the invited user
5557
- Sending messages to CCs or suppressing email messages altogether
5658

5759
## Code sample
58-
Here we illustrate how to call the invitation API, in "app-only" mode, to get the redemption URL for the resource to which you are inviting the B2B user. The goal is to send a custom invitation email. The email can be composed with an HTTP client, so you can customize how it looks and send it through the Microsoft Graph API.
60+
61+
The code sample illustrates how to call the invitation API and get the redemption URL. Use the redemption URL to send a custom invitation email. The email can be composed with an HTTP client, so you can customize how it looks and send it through the Microsoft Graph API.
62+
63+
64+
# [HTTP](#tab/http)
65+
66+
```http
67+
POST https://graph.microsoft.com/v1.0/invitations
68+
Content-type: application/json
69+
{
70+
"invitedUserEmailAddress": "[email protected]",
71+
"invitedUserDisplayName": "David",
72+
"inviteRedirectUrl": "https://myapp.contoso.com",
73+
"sendInvitationMessage": true
74+
}
75+
```
76+
77+
# [C#](#tab/csharp)
5978

6079
```csharp
80+
using System;
81+
using System.Threading.Tasks;
82+
using Microsoft.Graph;
83+
using Azure.Identity;
84+
6185
namespace SampleInviteApp
6286
{
63-
using System;
64-
using System.Linq;
65-
using System.Net.Http;
66-
using System.Net.Http.Headers;
67-
using Microsoft.IdentityModel.Clients.ActiveDirectory;
68-
using Newtonsoft.Json;
6987
class Program
7088
{
7189
/// <summary>
72-
/// Microsoft Graph resource.
73-
/// </summary>
74-
static readonly string GraphResource = "https://graph.microsoft.com";
75-
76-
/// <summary>
77-
/// Microsoft Graph invite endpoint.
78-
/// </summary>
79-
static readonly string InviteEndPoint = "https://graph.microsoft.com/v1.0/invitations";
80-
81-
/// <summary>
82-
///  Authentication endpoint to get token.
83-
/// </summary>
84-
static readonly string EstsLoginEndpoint = "https://login.microsoftonline.com";
85-
86-
/// <summary>
87-
/// This is the tenantid of the tenant you want to invite users to.
90+
/// This is the tenant ID of the tenant you want to invite users to.
8891
/// </summary>
8992
private static readonly string TenantID = "";
9093

9194
/// <summary>
9295
/// This is the application id of the application that is registered in the above tenant.
93-
/// The required scopes are available in the below link.
94-
/// https://developer.microsoft.com/graph/docs/api-reference/v1.0/api/invitation_post
9596
/// </summary>
9697
private static readonly string TestAppClientId = "";
9798

@@ -114,119 +115,106 @@ namespace SampleInviteApp
114115
/// Main method.
115116
/// </summary>
116117
/// <param name="args">Optional arguments</param>
117-
static void Main(string[] args)
118-
{
119-
Invitation invitation = CreateInvitation();
120-
SendInvitation(invitation);
121-
}
122-
123-
/// <summary>
124-
/// Create the invitation object.
125-
/// </summary>
126-
/// <returns>Returns the invitation object.</returns>
127-
private static Invitation CreateInvitation()
118+
static async Task Main(string[] args)
128119
{
129-
// Set the invitation object.
130-
Invitation invitation = new Invitation();
131-
invitation.InvitedUserDisplayName = InvitedUserDisplayName;
132-
invitation.InvitedUserEmailAddress = InvitedUserEmailAddress;
133-
invitation.InviteRedirectUrl = "https://www.microsoft.com";
134-
invitation.SendInvitationMessage = true;
135-
return invitation;
120+
string InviteRedeemUrl = await SendInvitation();
136121
}
137122

138123
/// <summary>
139124
/// Send the guest user invite request.
140125
/// </summary>
141-
/// <param name="invitation">Invitation object.</param>
142-
private static void SendInvitation(Invitation invitation)
126+
private static async string SendInvitation()
143127
{
144-
string accessToken = GetAccessToken();
128+
/// Get the access token for our application to talk to Microsoft Graph.
129+
var scopes = new[] { "https://graph.microsoft.com/.default" };
130+
var clientSecretCredential = new ClientSecretCredential(TenantID, TestAppClientId, TestAppClientSecret);
131+
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
145132

146-
HttpClient httpClient = GetHttpClient(accessToken);
147-
148-
// Make the invite call.
149-
HttpContent content = new StringContent(JsonConvert.SerializeObject(invitation));
150-
content.Headers.Add("ContentType", "application/json");
151-
var postResponse = httpClient.PostAsync(InviteEndPoint, content).Result;
152-
string serverResponse = postResponse.Content.ReadAsStringAsync().Result;
153-
Console.WriteLine(serverResponse);
133+
// Create the invitation object.
134+
var invitation = new Invitation
135+
{
136+
InvitedUserEmailAddress = InvitedUserEmailAddress,
137+
InvitedUserDisplayName = InvitedUserDisplayName,
138+
InviteRedirectUrl = "https://www.microsoft.com",
139+
SendInvitationMessage = true
140+
};
141+
142+
// Send the invitation
143+
var GraphResponse = await graphClient.Invitations
144+
.Request()
145+
.AddAsync(invitation);
146+
147+
// Return the invite redeem URL
148+
return GraphResponse.InviteRedeemUrl;
154149
}
150+
}
151+
}
152+
```
155153

156-
/// <summary>
157-
/// Get the HTTP client.
158-
/// </summary>
159-
/// <param name="accessToken">Access token</param>
160-
/// <returns>Returns the Http Client.</returns>
161-
private static HttpClient GetHttpClient(string accessToken)
162-
{
163-
// setup http client.
164-
HttpClient httpClient = new HttpClient();
165-
httpClient.Timeout = TimeSpan.FromSeconds(300);
166-
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
167-
httpClient.DefaultRequestHeaders.Add("client-request-id", Guid.NewGuid().ToString());
168-
Console.WriteLine(
169-
"CorrelationID for the request: {0}",
170-
httpClient.DefaultRequestHeaders.GetValues("client-request-id").Single());
171-
return httpClient;
172-
}
154+
# [JavaScript](#tab/javascript)
173155

174-
/// <summary>
175-
/// Get the access token for our application to talk to Microsoft Graph.
176-
/// </summary>
177-
/// <returns>Returns the access token for our application to talk to Microsoft Graph.</returns>
178-
private static string GetAccessToken()
179-
{
180-
string accessToken = null;
156+
Install the following npm packages:
181157

182-
// Get the access token for our application to talk to Microsoft Graph.
183-
try
184-
{
185-
AuthenticationContext testAuthContext =
186-
new AuthenticationContext(string.Format("{0}/{1}", EstsLoginEndpoint, TenantID));
187-
AuthenticationResult testAuthResult = testAuthContext.AcquireTokenAsync(
188-
GraphResource,
189-
new ClientCredential(TestAppClientId, TestAppClientSecret)).Result;
190-
accessToken = testAuthResult.AccessToken;
191-
}
192-
catch (AdalException ex)
193-
{
194-
Console.WriteLine("An exception was thrown while fetching the token: {0}.", ex);
195-
throw;
196-
}
197-
198-
return accessToken;
199-
}
158+
```bash
159+
npm install express
160+
npm install isomorphic-fetch
161+
npm install @azure/identity
162+
npm install @microsoft/microsoft-graph-client
163+
```
200164

201-
/// <summary>
202-
/// Invitation class.
203-
/// </summary>
204-
public class Invitation
205-
{
206-
/// <summary>
207-
/// Gets or sets display name.
208-
/// </summary>
209-
public string InvitedUserDisplayName { get; set; }
210-
211-
/// <summary>
212-
/// Gets or sets display name.
213-
/// </summary>
214-
public string InvitedUserEmailAddress { get; set; }
215-
216-
/// <summary>
217-
/// Gets or sets a value indicating whether Invitation Manager should send the email to InvitedUser.
218-
/// </summary>
219-
public bool SendInvitationMessage { get; set; }
220-
221-
/// <summary>
222-
/// Gets or sets invitation redirect URL
223-
/// </summary>
224-
public string InviteRedirectUrl { get; set; }
225-
}
226-
}
165+
```javascript
166+
const express = require('express')
167+
const app = express()
168+
169+
const { Client } = require("@microsoft/microsoft-graph-client");
170+
const { TokenCredentialAuthenticationProvider } = require("@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials");
171+
const { ClientSecretCredential } = require("@azure/identity");
172+
require("isomorphic-fetch");
173+
174+
// This is the application id of the application that is registered in the above tenant.
175+
const CLIENT_ID = ""
176+
177+
// Client secret of the application.
178+
const CLIENT_SECRET = ""
179+
180+
// This is the tenant ID of the tenant you want to invite users to. For example fabrikam.onmicrosoft.com
181+
const TENANT_ID = ""
182+
183+
async function sendInvite() {
184+
185+
// Initialize a confidential client application. For more info, visit: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-service-principal-with-a-client-secret
186+
const credential = new ClientSecretCredential(TENANT_ID, CLIENT_ID, CLIENT_SECRET);
187+
188+
// Initialize the Microsoft Graph authentication provider. For more info, visit: https://docs.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=Javascript#using--for-server-side-applications
189+
const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ['https://graph.microsoft.com/.default'] });
190+
191+
// Create MS Graph client instance. For more info, visit: https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CreatingClientInstance.md
192+
const client = Client.initWithMiddleware({
193+
debugLogging: true,
194+
authProvider,
195+
});
196+
197+
// Create invitation object
198+
const invitation = {
199+
invitedUserEmailAddress: '[email protected]',
200+
invitedUserDisplayName: 'David',
201+
inviteRedirectUrl: 'https://www.microsoft.com',
202+
sendInvitationMessage: true
203+
};
204+
205+
// Execute the MS Graph command. For more information, visit: https://docs.microsoft.com/en-us/graph/api/invitation-post
206+
graphResponse = await client.api('/invitations')
207+
.post(invitation);
208+
209+
// Return the invite redeem URL
210+
return graphResponse.inviteRedeemUrl
227211
}
212+
213+
const inviteRedeemUrl = await sendInvite();
214+
228215
```
229216

217+
---
230218

231219
## Next steps
232220

articles/api-management/api-management-advanced-policies.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ The second control flow policy is in the outbound section and conditionally appl
9696

9797
#### Example
9898

99-
This example shows how to perform content filtering by removing data elements from the response received from the backend service when using the `Starter` product. For a demonstration of configuring and using this policy, see [Cloud Cover Episode 177: More API Management Features with Vlad Vinogradsky](https://azure.microsoft.com/documentation/videos/episode-177-more-api-management-features-with-vlad-vinogradsky/) and fast-forward to 34:30. Start at 31:50 to see an overview of [The Dark Sky Forecast API](https://developer.forecast.io/) used for this demo.
99+
This example shows how to perform content filtering by removing data elements from the response received from the backend service when using the `Starter` product. The example backend response includes root-level properties similar to the [OpenWeather One Call API](https://openweathermap.org/api/one-call-api).
100100

101101
```xml
102-
<!-- Copy this snippet into the outbound section to remove a number of data elements from the response received from the backend service based on the name of the api product -->
102+
<!-- Copy this snippet into the outbound section to remove a number of data elements from the response received from the backend service based on the name of the product -->
103103
<choose>
104104
<when condition="@(context.Response.StatusCode == 200 && context.Product.Name.Equals("Starter"))">
105105
<set-body>@{
106106
var response = context.Response.Body.As<JObject>();
107-
foreach (var key in new [] {"minutely", "hourly", "daily", "flags"}) {
107+
foreach (var key in new [] {"current", "minutely", "hourly", "daily", "alerts"}) {
108108
response.Property (key).Remove ();
109109
}
110110
return response.ToString();

articles/api-management/api-management-caching-policies.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Use the `cache-lookup` policy to perform cache look up and return a valid cached
7373
```
7474

7575
#### Example using policy expressions
76-
This example shows how to configure API Management response caching duration that matches the response caching of the backend service as specified by the backed service's `Cache-Control` directive. For a demonstration of configuring and using this policy, see [Cloud Cover Episode 177: More API Management Features with Vlad Vinogradsky](https://azure.microsoft.com/documentation/videos/episode-177-more-api-management-features-with-vlad-vinogradsky/) and fast-forward to 25:25.
76+
This example shows how to configure API Management response caching duration that matches the response caching of the backend service as specified by the backend service's `Cache-Control` directive.
7777

7878
```xml
7979
<!-- The following cache policy snippets demonstrate how to control API Management response cache duration with Cache-Control headers sent by the backend service. -->
@@ -152,7 +152,7 @@ The `cache-store` policy caches responses according to the specified cache setti
152152
```
153153

154154
#### Example using policy expressions
155-
This example shows how to configure API Management response caching duration that matches the response caching of the backend service as specified by the backed service's `Cache-Control` directive. For a demonstration of configuring and using this policy, see Cloud Cover Episode 177: More API Management Features with Vlad Vinogradsky and fast-forward to 25:25.
155+
This example shows how to configure API Management response caching duration that matches the response caching of the backend service as specified by the backend service's `Cache-Control` directive.
156156

157157
```xml
158158
<!-- The following cache policy snippets demonstrate how to control API Management response cache duration with Cache-Control headers sent by the backend service. -->

articles/api-management/api-management-transformation-policies.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -337,15 +337,15 @@ In this example the policy routes the request to a service fabric backend, using
337337
```
338338

339339
#### Filter response based on product
340-
This example shows how to perform content filtering by removing data elements from the response received from the backend service when using the `Starter` product. For a demonstration of configuring and using this policy, see [Cloud Cover Episode 177: More API Management Features with Vlad Vinogradsky](https://azure.microsoft.com/documentation/videos/episode-177-more-api-management-features-with-vlad-vinogradsky/) and fast-forward to 34:30. Start at 31:50 to see an overview of [The Dark Sky Forecast API](https://developer.forecast.io/) used for this demo.
340+
This example shows how to perform content filtering by removing data elements from the response received from a backend service when using the `Starter` product. The example backend response includes root-level properties similar to the [OpenWeather One Call API](https://openweathermap.org/api/one-call-api).
341341

342342
```xml
343-
<!-- Copy this snippet into the outbound section to remove a number of data elements from the response received from the backend service based on the name of the api product -->
343+
<!-- Copy this snippet into the outbound section to remove a number of data elements from the response received from the backend service based on the name of the product -->
344344
<choose>
345345
<when condition="@(context.Response.StatusCode == 200 && context.Product.Name.Equals("Starter"))">
346346
<set-body>@{
347347
var response = context.Response.Body.As<JObject>();
348-
foreach (var key in new [] {"minutely", "hourly", "daily", "flags"}) {
348+
foreach (var key in new [] {"current", "minutely", "hourly", "daily", "alerts"}) {
349349
response.Property (key).Remove ();
350350
}
351351
return response.ToString();
@@ -479,7 +479,7 @@ OriginalUrl.
479479

480480

481481
#### Forward context information to the backend service
482-
This example shows how to apply policy at the API level to supply context information to the backend service. For a demonstration of configuring and using this policy, see [Cloud Cover Episode 177: More API Management Features with Vlad Vinogradsky](https://azure.microsoft.com/documentation/videos/episode-177-more-api-management-features-with-vlad-vinogradsky/) and fast-forward to 10:30. At 12:10 there is a demo of calling an operation in the developer portal where you can see the policy at work.
482+
This example shows how to apply policy at the API level to supply context information to the backend service.
483483

484484
```xml
485485
<!-- Copy this snippet into the inbound element to forward some context information, user id and the region the gateway is hosted in, to the backend service for logging or evaluation -->
@@ -495,7 +495,7 @@ OriginalUrl.
495495
> Multiple values of a header are concatenated to a CSV string, for example:
496496
> `headerName: value1,value2,value3`
497497
>
498-
> Exceptions include standardized headers, which values:
498+
> Exceptions include standardized headers whose values:
499499
> - may contain commas (`User-Agent`, `WWW-Authenticate`, `Proxy-Authenticate`),
500500
> - may contain date (`Cookie`, `Set-Cookie`, `Warning`),
501501
> - contain date (`Date`, `Expires`, `If-Modified-Since`, `If-Unmodified-Since`, `Last-Modified`, `Retry-After`).
@@ -548,7 +548,7 @@ OriginalUrl.
548548
```
549549

550550
#### Forward context information to the backend service
551-
This example shows how to apply policy at the API level to supply context information to the backend service. For a demonstration of configuring and using this policy, see [Cloud Cover Episode 177: More API Management Features with Vlad Vinogradsky](https://azure.microsoft.com/documentation/videos/episode-177-more-api-management-features-with-vlad-vinogradsky/) and fast-forward to 10:30. At 12:10 there is a demo of calling an operation in the developer portal where you can see the policy at work.
551+
This example shows how to apply policy at the API level to supply context information to the backend service.
552552

553553
```xml
554554
<!-- Copy this snippet into the inbound element to forward a piece of context, product name in this example, to the backend service for logging or evaluation -->

0 commit comments

Comments
 (0)