Skip to content

Commit 1c33917

Browse files
authored
[core-rest-pipeline] Challenge callbacks (Azure#13888)
This PR adds Continuous Assessment Evaluation (CAE) support to core-rest-pipeline. CAE support at the core level is about the following: - Some way to pre-process requests. - Some way to identify challenges. - Some way to process challenges. - Some way to handle the challenges, for example, use "scope" and "claims" from the challenges in the subsequent calls to retrieve access tokens. For more information about CAE, see https://docs.microsoft.com/azure/active-directory/conditional-access/concept-continuous-access-evaluation The changes this PR introduces: - Add a new `bearerTokenChallengeAuthenticationPolicy` that provides a skeleton of handling CAE flow. There are two extensible points: `authorizeRequest` and `authroizeRequestOnChallenge` callbacks. - `authorizeRequest` allows customizing the policy to alter how it authorizes a request before sending it. By default when no callbacks are specified, this policy has the same behavior as `bearerTokenAuthenticationPolicy`. It will retrieve the token from the underlying token credential, and if it gets one, it will cache the token and set it to the outgoing request.. - `authorizeRequestOnChallenge`, which gets called only if we've found a challenge in the response. This callback has access to the original request and its response and is expected to handle the challenge. If this callback returns true, the request, usually updated after handling the challenge, will be sent again. If this call back returns false, no further actions will be taken. Fixes Azure#13156
1 parent d79b277 commit 1c33917

File tree

11 files changed

+714
-38
lines changed

11 files changed

+714
-38
lines changed

common/config/rush/pnpm-lock.yaml

Lines changed: 34 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/core/core-rest-pipeline/CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# Release History
22

3-
## 1.0.4 (Unreleased)
3+
## 1.1.0-beta.1 (Unreleased)
44

5-
- Rewrote `bearerTokenAuthenticationPolicy` to use a new backend that refreshes tokens only when they're about to expire and not multiple times before. This is based on a similar fix implemented on `@azure/core-http@1.2.4` ([PR with the changes](https://github.com/Azure/azure-sdk-for-js/pull/14223)). This fixes the issue: [13369](https://github.com/Azure/azure-sdk-for-js/issues/13369).
5+
- Add a new `bearerTokenChallengeAuthenticationPolicy` that provides a skeleton of handling challenge-based authorization. There are two extensible points: `authorizeRequest` and `authorizeRequestOnChallenge` callbacks.
6+
- `authorizeRequest` allows customizing the policy to alter how it authorizes a request before sending it. By default when no callbacks are specified, this policy has the same behavior as `bearerTokenAuthenticationPolicy`. It will retrieve the token from the underlying token credential, and if it gets one, it will cache the token and set it to the outgoing request.
7+
- `authorizeRequestOnChallenge`, which gets called only if we've found a challenge in the response. This callback has access to the original request and its response and is expected to handle the challenge. If this callback returns true, the request, usually updated after handling the challenge, will be sent again. If this call back returns false, no further actions will be taken.
68

79
## 1.0.3 (2021-03-30)
810

sdk/core/core-rest-pipeline/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@azure/core-rest-pipeline",
3-
"version": "1.0.4",
3+
"version": "1.1.0-beta.1",
44
"description": "Isomorphic client library for making HTTP requests in node.js and browser.",
55
"sdk-type": "client",
66
"main": "dist/index.js",

sdk/core/core-rest-pipeline/review/core-rest-pipeline.api.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
```ts
66

77
import { AbortSignalLike } from '@azure/abort-controller';
8+
import { AccessToken } from '@azure/core-auth';
89
import { Debugger } from '@azure/logger';
10+
import { GetTokenOptions } from '@azure/core-auth';
911
import { OperationTracingOptions } from '@azure/core-tracing';
1012
import { TokenCredential } from '@azure/core-auth';
1113

@@ -26,6 +28,21 @@ export interface Agent {
2628
sockets: unknown;
2729
}
2830

31+
// @public
32+
export interface AuthorizeRequestOnChallengeOptions {
33+
getAccessToken: (scopes: string[], options: GetTokenOptions) => Promise<AccessToken | null>;
34+
request: PipelineRequest;
35+
response: PipelineResponse;
36+
scopes: string[];
37+
}
38+
39+
// @public
40+
export interface AuthorizeRequestOptions {
41+
getAccessToken: (scopes: string[], options: GetTokenOptions) => Promise<AccessToken | null>;
42+
request: PipelineRequest;
43+
scopes: string[];
44+
}
45+
2946
// @public
3047
export function bearerTokenAuthenticationPolicy(options: BearerTokenAuthenticationPolicyOptions): PipelinePolicy;
3148

@@ -38,6 +55,25 @@ export interface BearerTokenAuthenticationPolicyOptions {
3855
scopes: string | string[];
3956
}
4057

58+
// @public
59+
export function bearerTokenChallengeAuthenticationPolicy(options: BearerTokenChallengeAuthenticationPolicyOptions): PipelinePolicy;
60+
61+
// @public
62+
export const bearerTokenChallengeAuthenticationPolicyName = "bearerTokenChallengeAuthenticationPolicy";
63+
64+
// @public
65+
export interface BearerTokenChallengeAuthenticationPolicyOptions {
66+
challengeCallbacks?: ChallengeCallbacks;
67+
credential: TokenCredential;
68+
scopes: string[];
69+
}
70+
71+
// @public
72+
export interface ChallengeCallbacks {
73+
authorizeRequest?(options: AuthorizeRequestOptions): Promise<void>;
74+
authorizeRequestOnChallenge?(options: AuthorizeRequestOnChallengeOptions): Promise<boolean>;
75+
}
76+
4177
// @public
4278
export function createDefaultHttpClient(): HttpClient;
4379

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
33

4-
export const SDK_VERSION: string = "1.0.4";
4+
export const SDK_VERSION: string = "1.1.0-beta.1";

sdk/core/core-rest-pipeline/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,12 @@ export {
6868
BearerTokenAuthenticationPolicyOptions,
6969
bearerTokenAuthenticationPolicyName
7070
} from "./policies/bearerTokenAuthenticationPolicy";
71+
export {
72+
bearerTokenChallengeAuthenticationPolicy,
73+
BearerTokenChallengeAuthenticationPolicyOptions,
74+
bearerTokenChallengeAuthenticationPolicyName,
75+
ChallengeCallbacks,
76+
AuthorizeRequestOptions,
77+
AuthorizeRequestOnChallengeOptions
78+
} from "./policies/bearerTokenChallengeAuthenticationPolicy";
7179
export { ndJsonPolicy, ndJsonPolicyName } from "./policies/ndJsonPolicy";

sdk/core/core-rest-pipeline/src/policies/bearerTokenAuthenticationPolicy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ export function bearerTokenAuthenticationPolicy(
3838
// The options are left out of the public API until there's demand to configure this.
3939
// Remember to extend `BearerTokenAuthenticationPolicyOptions` with `TokenCyclerOptions`
4040
// in order to pass through the `options` object.
41-
const getToken = createTokenCycler(credential, scopes /* , options */);
41+
const cycler = createTokenCycler(credential /* , options */);
4242

4343
return {
4444
name: bearerTokenAuthenticationPolicyName,
4545
async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {
46-
const { token } = await getToken({
46+
const { token } = await cycler.getToken(scopes, {
4747
abortSignal: request.abortSignal,
4848
tracingOptions: request.tracingOptions
4949
});

0 commit comments

Comments
 (0)