Skip to content

Commit 621ca7e

Browse files
authored
Merge pull request #227457 from MicrosoftDocs/main
2/15 AM Publish
2 parents 2730675 + 93ccbb7 commit 621ca7e

File tree

78 files changed

+977
-496
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+977
-496
lines changed

articles/active-directory/app-provisioning/user-provisioning.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ms.service: active-directory
77
ms.subservice: app-provisioning
88
ms.topic: overview
99
ms.workload: identity
10-
ms.date: 02/14/2023
10+
ms.date: 02/15/2023
1111
ms.author: kenwith
1212
ms.reviewer: arvinh
1313
---
@@ -35,7 +35,7 @@ App provisioning lets you:
3535

3636
## What is SCIM?
3737

38-
To help automate provisioning and deprovisioning, apps expose proprietary user and group APIs. But anyone who's tried to manage users in more than one app will tell you that every app tries to perform the same actions, such as creating or updating users, adding users to groups, or deprovisioning users. Yet, all these actions are implemented slightly differently by using different endpoint paths, different methods to specify user information, and a different schema to represent each element of information.
38+
To help automate provisioning and deprovisioning, apps expose proprietary user and group APIs. User management in more than one app is a challenge because every app tries to perform the same actions. For example, creating or updating users, adding users to groups, or deprovisioning users. Yet, all these actions are implemented slightly differently by using different endpoint paths, different methods to specify user information, and a different schema to represent each element of information.
3939

4040
To address these challenges, the System for Cross-domain Identity Management (SCIM) specification provides a common user schema to help users move into, out of, and around apps. SCIM is becoming the de facto standard for provisioning and, when used with federation standards like Security Assertions Markup Language (SAML) or OpenID Connect (OIDC), provides administrators an end-to-end standards-based solution for access management.
4141

@@ -52,7 +52,7 @@ The provisioning mode supported by an application is also visible on the **Provi
5252

5353
## Benefits of automatic provisioning
5454

55-
As the number of applications used in modern organizations continues to grow, IT admins are tasked with access management at scale. Standards such as SAML or OIDC allow admins to quickly set up single sign-on (SSO), but access also requires users to be provisioned into the app. To many admins, provisioning means manually creating every user account or uploading CSV files each week. These processes are time-consuming, expensive, and error prone. Solutions such as SAML just-in-time (JIT) have been adopted to automate provisioning. Enterprises also need a solution to deprovision users when they leave the organization or no longer require access to certain apps based on role change.
55+
The number of applications used in modern organizations continues to grow. IT admins are tasked with access management at scale. Admins use standards such as SAML or OIDC for single sign-on (SSO), but access also requires users to be provisioned into the app. To many admins, provisioning means manually creating every user account or uploading CSV files each week. These processes are time-consuming, expensive, and error prone. Solutions such as SAML just-in-time (JIT) have been adopted to automate provisioning. Enterprises also need a solution to deprovision users when they leave the organization or no longer require access to certain apps based on role change.
5656

5757
Some common motivations for using automatic provisioning include:
5858

articles/active-directory/develop/reference-aadsts-error-codes.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ The `error` field has several possible values - review the protocol documentatio
238238
| AADSTS75008 | RequestDeniedError - The request from the app was denied since the SAML request had an unexpected destination. |
239239
| AADSTS75011 | NoMatchedAuthnContextInOutputClaims - The authentication method by which the user authenticated with the service doesn't match requested authentication method. To learn more, see the troubleshooting article for error [AADSTS75011](/troubleshoot/azure/active-directory/error-code-aadsts75011-auth-method-mismatch). |
240240
| AADSTS75016 | Saml2AuthenticationRequestInvalidNameIDPolicy - SAML2 Authentication Request has invalid NameIdPolicy. |
241+
| AADSTS76026 | RequestIssueTimeExpired - IssueTime in an SAML2 Authentication Request is expired. |
241242
| AADSTS80001 | OnPremiseStoreIsNotAvailable - The Authentication Agent is unable to connect to Active Directory. Make sure that agent servers are members of the same AD forest as the users whose passwords need to be validated and they are able to connect to Active Directory. |
242243
| AADSTS80002 | OnPremisePasswordValidatorRequestTimedout - Password validation request timed out. Make sure that Active Directory is available and responding to requests from the agents. |
243244
| AADSTS80005 | OnPremisePasswordValidatorUnpredictableWebException - An unknown error occurred while processing the response from the Authentication Agent. Retry the request. If it continues to fail, [open a support ticket](../fundamentals/active-directory-troubleshooting-support-howto.md) to get more details on the error. |
@@ -368,4 +369,4 @@ The `error` field has several possible values - review the protocol documentatio
368369

369370
## Next steps
370371

371-
* Have a question or can't find what you're looking for? Create a GitHub issue or see [Support and help options for developers](./developer-support-help-options.md) to learn about other ways you can get help and support.
372+
* Have a question or can't find what you're looking for? Create a GitHub issue or see [Support and help options for developers](./developer-support-help-options.md) to learn about other ways you can get help and support.

articles/active-directory/develop/test-automate-integration-testing.md

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,11 @@ To exclude a test application:
122122

123123
## Write your application tests
124124

125-
Now that you're set up, you can write your automated tests. The following .NET example code uses [Microsoft Authentication Library (MSAL)](msal-overview.md) and [xUnit](https://xunit.net/), a common testing framework.
125+
Now that you're set up, you can write your automated tests. The following are tests for:
126+
1. .NET example code uses [Microsoft Authentication Library (MSAL)](msal-overview.md) and [xUnit](https://xunit.net/), a common testing framework.
127+
1. JavaScript example code uses [Microsoft Authentication Library (MSAL)](msal-overview.md) and [Playwright](https://playwright.dev/), a common testing framework.
128+
129+
## [.NET](#tab/dotnet)
126130

127131
### Set up your appsettings.json file
128132

@@ -252,3 +256,112 @@ public class ApiTests : IClassFixture<ClientFixture>
252256
}
253257
}
254258
```
259+
260+
## [JavaScript](#tab/JavaScript)
261+
262+
### Set up your authConfig.json file
263+
264+
Add the client ID and the tenant ID of the test app you previously created, the key vault URI and the secret name to the authConfig.js file of your test project.
265+
266+
```javascript
267+
export const msalConfig = {
268+
auth: {
269+
clientId: 'Enter_the_Application_Id_Here',
270+
authority: 'https://login.microsoftonline.com/Enter_the_Tenant_Id_Here',
271+
},
272+
};
273+
274+
export const keyVaultConfig = {
275+
keyVaultUri: 'https://<your-unique-keyvault-name>.vault.azure.net',
276+
secretName: 'Enter_the_Secret_Name',
277+
};
278+
```
279+
280+
### Initialize MSAL.js and fetch the user credentials from Key Vault
281+
282+
Initialize the MSAL.js authentication context by instantiating a [PublicClientApplication](https://azuread.github.io/microsoft-authentication-library-for-js/ref/classes/_azure_msal_browser.publicclientapplication.html) with a [Configuration](https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal.html#configuration) object. The minimum required configuration property is the `clientID` of the application.
283+
284+
Use [SecretClient()](/javascript/api/@azure/keyvault-secrets/secretclient) to get the test username and password secrets from Azure Key Vault.
285+
286+
[DefaultAzureCredential()](/javascript/api/@azure/identity/defaultazurecredential) authenticates with Azure Key Vault by getting an access token from a service principal configured by environment variables or a managed identity (if the code is running on an Azure resource with a managed identity). If the code is running locally, `DefaultAzureCredential` uses the local user's credentials. Read more in the [Azure Identity client library](/javascript/api/@azure/identity/defaultazurecredential) content.
287+
288+
Use Microsoft Authentication Library (MSAL) to authenticate using the ROPC flow and get an access token. The access token is passed along as a bearer token in the HTTP request.
289+
290+
291+
```javascript
292+
import { test, expect } from '@playwright/test';
293+
import { DefaultAzureCredential } from '@azure/identity';
294+
import { SecretClient } from '@azure/keyvault-secrets';
295+
import { PublicClientApplication, CacheKVStore } from '@azure/msal-node';
296+
import { msalConfig, keyVaultConfig } from '../authConfig';
297+
298+
let tokenCache;
299+
const KVUri = keyVaultConfig.keyVaultUri;
300+
const secretName = keyVaultConfig.secretName;
301+
302+
async function getCredentials() {
303+
try {
304+
const credential = new DefaultAzureCredential();
305+
const secretClient = new SecretClient(KVUri, credential);
306+
const secret = await secretClient.getSecret(keyVaultConfig.secretName);
307+
const password = secret.value;
308+
return [secretName, password];
309+
} catch (error) {
310+
console.log(error);
311+
}
312+
}
313+
314+
test.beforeAll(async () => {
315+
const pca = new PublicClientApplication(msalConfig);
316+
const [username, password] = await getCredentials();
317+
const usernamePasswordRequest = {
318+
scopes: ['user.read', 'User.ReadBasic.All'],
319+
username: username,
320+
password: password,
321+
};
322+
await pca.acquireTokenByUsernamePassword(usernamePasswordRequest);
323+
tokenCache = pca.getTokenCache().getKVStore();
324+
});
325+
```
326+
327+
### Run the test suite
328+
329+
In the same file, add the tests as shown below:
330+
331+
```javascript
332+
/**
333+
* Stores the token in the session storage and reloads the page
334+
*/
335+
async function setSessionStorage(page, tokens) {
336+
const cacheKeys = Object.keys(tokens);
337+
for (let key of cacheKeys) {
338+
const value = JSON.stringify(tokenCache[key]);
339+
await page.context().addInitScript(
340+
(arr) => {
341+
window.sessionStorage.setItem(arr[0], arr[1]);
342+
},
343+
[key, value]
344+
);
345+
}
346+
await page.reload();
347+
}
348+
349+
test.describe('Testing Authentication with MSAL.js ', () => {
350+
test('Test user has signed in successfully', async ({ page }) => {
351+
await page.goto('http://localhost:<port>/');
352+
let signInButton = page.getByRole('button', { name: /Sign In/i });
353+
let signOutButton = page.getByRole('button', { name: /Sign Out/i });
354+
let welcomeDev = page.getByTestId('WelcomeMessage');
355+
expect(await signInButton.count()).toBeGreaterThan(0);
356+
expect(await signOutButton.count()).toBeLessThanOrEqual(0);
357+
expect(await welcomeDev.innerHTML()).toEqual('Please sign-in to see your profile and read your mails');
358+
await setSessionStorage(page, tokenCache);
359+
expect(await signInButton.count()).toBeLessThanOrEqual(0);
360+
expect(await signOutButton.count()).toBeGreaterThan(0);
361+
expect(await welcomeDev.innerHTML()).toContain(`Welcome`);
362+
});
363+
});
364+
365+
```
366+
367+
For more information, please check the following code sample [MSAL.js Testing Example](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/msal-browser-samples/TestingSample).

0 commit comments

Comments
 (0)