Skip to content

Commit 36167c2

Browse files
authored
Merge pull request #204780 from salman90/updating-continuous-access-evaluation
Updated the continuous access evaluation docs to include JavaScript implementation
2 parents 20b7207 + 8eb1057 commit 36167c2

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed

articles/active-directory/develop/app-resilience-continuous-access-evaluation.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ Your app would check for:
4747
- an "error" parameter with the value "insufficient_claims"
4848
- a "claims" parameter
4949

50+
# [.NET](#tab/dotnet)
51+
5052
When these conditions are met, the app can extract and decode the claims challenge using MSAL.NET `WwwAuthenticateParameters` class.
5153

5254
```csharp
@@ -97,7 +99,69 @@ _clientApp = PublicClientApplicationBuilder.Create(App.ClientId)
9799

98100
You can test your application by signing in a user to the application then using the Azure portal to Revoke the user's sessions. The next time the app calls the CAE enabled API, the user will be asked to reauthenticate.
99101

102+
# [JavaScript](#tab/JavaScript)
103+
104+
When these conditions are met, the app can extract the claims challenge from the API response header as follows:
105+
106+
```javascript
107+
const authenticateHeader = response.headers.get('www-authenticate');
108+
const claimsChallenge = authenticateHeader
109+
.split(' ')
110+
.find((entry) => entry.includes('claims='))
111+
.split('claims="')[1]
112+
.split('",')[0];
113+
```
114+
115+
Your app would then use the claims challenge to acquire a new access token for the resource.
116+
117+
```javascript
118+
let tokenResponse;
119+
120+
try {
121+
122+
tokenResponse = await msalInstance.acquireTokenSilent({
123+
claims: window.atob(claimsChallenge), // decode the base64 string
124+
scopes: scopes, // e.g ['User.Read', 'Contacts.Read']
125+
account: account, // current active account
126+
});
127+
128+
} catch (error) {
129+
130+
if (error instanceof InteractionRequiredAuthError) {
131+
132+
tokenResponse = await msalInstance.acquireTokenPopup({
133+
claims: window.atob(claimsChallenge), // decode the base64 string
134+
scopes: scopes, // e.g ['User.Read', 'Contacts.Read']
135+
account: account, // current active account
136+
});
137+
}
138+
139+
}
140+
```
141+
142+
Once your application is ready to handle the claim challenge returned by a CAE-enabled resource, you can tell Microsoft Identity your app is CAE-ready by adding a `clientCapabilities` property in the MSAL configuration.
143+
144+
```javascript
145+
const msalConfig = {
146+
auth: {
147+
clientId: 'Enter_the_Application_Id_Here',
148+
clientCapabilities: ["CP1"]
149+
// the remaining settings
150+
// ...
151+
}
152+
}
153+
154+
const msalInstance = new PublicClientApplication(msalConfig);
155+
156+
```
157+
158+
---
159+
160+
You can test your application by signing in a user and then using the Azure portal to revoke the user's session. The next time the app calls the CAE-enabled API, the user will be asked to reauthenticate.
161+
100162
## Next steps
101163

102164
- [Continuous access evaluation](../conditional-access/concept-continuous-access-evaluation.md) conceptual overview
103165
- [Claims challenges, claims requests, and client capabilities](claims-challenge.md)
166+
- [React single-page application using MSAL React to sign-in users against Azure Active Directory](https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/tree/main/2-Authorization-I/1-call-graph)
167+
- [Enable your ASP.NET Core web app to sign in users and call Microsoft Graph with the Microsoft identity platform](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/2-WebApp-graph-user/2-1-Call-MSGraph)

articles/active-directory/develop/claims-challenge.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ The following example claims parameter shows how a client application communicat
9494
Claims: {"access_token":{"xms_cc":{"values":["cp1"]}}}
9595
```
9696

97+
#### [.NET](#tab/dotnet)
98+
9799
Those using MSAL library will use the following code:
98100

99101
```c#
@@ -115,6 +117,24 @@ Those using Microsoft.Identity.Web can add the following code to the configurati
115117
"ClientCapabilities": [ "cp1" ]
116118
},
117119
```
120+
#### [JavaScript](#tab/JavaScript)
121+
122+
Those using MSAL.js can add `clientCapabilities` property to the configuration object.
123+
124+
```javascript
125+
const msalConfig = {
126+
auth: {
127+
clientId: 'Enter_the_Application_Id_Here',
128+
clientCapabilities: ["CP1"]
129+
// the remaining settings
130+
// ...
131+
}
132+
}
133+
134+
const msalInstance = new msal.PublicClientApplication(msalConfig);
135+
```
136+
137+
---
118138

119139
An example of how the request to Azure AD will look like:
120140

@@ -152,7 +172,7 @@ The **xms_cc** claim with a value of "cp1" in the access token is the authoritat
152172

153173
The values are not case-sensitive and unordered. If more than one value is specified in the **xms_cc** claim request, those values will be a multi-valued collection as the value of the **xms_cc** claim.
154174

155-
A request of :
175+
A request of:
156176

157177
```json
158178
{ "access_token": { "xms_cc":{"values":["cp1","foo", "bar"] } }}
@@ -185,7 +205,7 @@ This is how the app's manifest looks like after the **xms_cc** [optional claim](
185205

186206
The API can then customize their responses based on whether the client is capable of handling claims challenge or not.
187207

188-
An example in C#
208+
### [.NET](#tab/dotnet)
189209

190210
```c#
191211
Claim ccClaim = context.User.FindAll(clientCapabilitiesClaim).FirstOrDefault(x => x.Type == "xms_cc");
@@ -200,8 +220,27 @@ else
200220
}
201221
```
202222

223+
### [JavaScript](#tab/JavaScript)
224+
225+
```javascript
226+
const checkIsClientCapableOfClaimsChallenge = (req, res, next) => {
227+
// req.authInfo contains the decoded access token payload
228+
if (req.authInfo['xms_cc'] && req.authInfo['xms_cc'].includes('CP1')) {
229+
// Return formatted claims challenge as this client understands this
230+
231+
} else {
232+
return res.status(403).json({ error: 'Client is not capable' });
233+
}
234+
}
235+
236+
```
237+
238+
---
239+
203240
## Next steps
204241

205242
- [Microsoft identity platform and OAuth 2.0 authorization code flow](v2-oauth2-auth-code-flow.md#request-an-authorization-code)
206243
- [How to use Continuous Access Evaluation enabled APIs in your applications](app-resilience-continuous-access-evaluation.md)
207244
- [Granular Conditional Access for sensitive data and actions](https://techcommunity.microsoft.com/t5/azure-active-directory-identity/granular-conditional-access-for-sensitive-data-and-actions/ba-p/1751775)
245+
- [React single-page application using MSAL React to sign-in users against Azure Active Directory](https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/tree/main/2-Authorization-I/1-call-graph)
246+
- [Enable your ASP.NET Core web app to sign in users and call Microsoft Graph with the Microsoft identity platform](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/2-WebApp-graph-user/2-1-Call-MSGraph)

0 commit comments

Comments
 (0)