Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ public static void AddAuthorizationHeaderRequestEndpoints(this WebApplication ap
ProducesProblem(StatusCodes.Status401Unauthorized).
WithSummary("Get an authorization header for a configured downstream API.").
WithDescription(
"This endpoint will use the identity of the authenticated request to acquire an authorization header." +
"This endpoint will use the identity of the authenticated request to acquire an authorization header. " +
"Use dotted query parameters prefixed with 'optionsOverride.' to override call settings with respect to the configuration. " +
"Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:GetAuthorizationHeader' (default: true). " +
"Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. " +
"'optionsOverride.BaseUrl' is always ignored. " +
"Examples:\n" +
" ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n" +
Expand All @@ -66,9 +67,10 @@ public static void AddAuthorizationHeaderRequestEndpoints(this WebApplication ap
ProducesProblem(StatusCodes.Status401Unauthorized).
WithSummary("Get an authorization header for a configured downstream API using this configured client credentials.").
WithDescription(
"This endpoint will use the configured client credentials to acquire an authorization header." +
"This endpoint will use the configured client credentials to acquire an authorization header. " +
"Use dotted query parameters prefixed with 'optionsOverride.' to override call settings with respect to the configuration. " +
"Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:GetAuthorizationHeaderUnauthenticated' (default: false). " +
"Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. " +
"'optionsOverride.BaseUrl' is always ignored. " +
"Examples:\n" +
" ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n" +
Expand Down Expand Up @@ -117,7 +119,14 @@ public static void AddAuthorizationHeaderRequestEndpoints(this WebApplication ap
statusCode: StatusCodes.Status400BadRequest);
}

AgentOverrides.SetOverrides(options, requestParameters.AgentIdentity, requestParameters.AgentUsername, requestParameters.AgentUserId);
if (allowOverrides)
{
AgentOverrides.SetOverrides(options, requestParameters.AgentIdentity, requestParameters.AgentUsername, requestParameters.AgentUserId);
}
else if (requestParameters.AgentIdentity is not null || requestParameters.AgentUsername is not null || requestParameters.AgentUserId is not null)
{
logger.AgentIdentityOverridesIgnored(routeName);
}

string authorizationHeader;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public static void AddDownstreamApiRequestEndpoints(this WebApplication app)
WithDescription(
"Override downstream call options using dotted query parameters prefixed with 'optionsOverride.'. " +
"Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:CallDownstreamApi' (default: true). " +
"Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. " +
"'optionsOverride.BaseUrl' is always ignored. " +
"Examples:\n" +
" ?optionsOverride.Scopes=User.Read\n" +
Expand Down Expand Up @@ -69,6 +70,7 @@ public static void AddDownstreamApiRequestEndpoints(this WebApplication app)
WithDescription(
"Override downstream call options using dotted query parameters prefixed with 'optionsOverride.'. " +
"Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:CallDownstreamApiUnauthenticated' (default: false). " +
"Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. " +
"'optionsOverride.BaseUrl' is always ignored. " +
"Examples:\n" +
" ?optionsOverride.Scopes=User.Read\n" +
Expand Down Expand Up @@ -117,7 +119,14 @@ private static async Task<Results<Ok<DownstreamApiResult>, ProblemHttpResult>> D
statusCode: StatusCodes.Status400BadRequest);
}

AgentOverrides.SetOverrides(options, requestParameters.AgentIdentity, requestParameters.AgentUsername, requestParameters.AgentUserId);
if (allowOverrides)
{
AgentOverrides.SetOverrides(options, requestParameters.AgentIdentity, requestParameters.AgentUsername, requestParameters.AgentUserId);
}
else if (requestParameters.AgentIdentity is not null || requestParameters.AgentUsername is not null || requestParameters.AgentUserId is not null)
{
logger.AgentIdentityOverridesIgnored(routeName);
}

HttpContent? content = null;

Expand Down
7 changes: 7 additions & 0 deletions src/Microsoft.Identity.Web.Sidecar/Logging/Logging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,11 @@ public static partial class LoggerMessageExtensions
Message = "Caller-supplied 'optionsOverride.BaseUrl' was ignored. The downstream BaseUrl is fixed by the host configuration and cannot be overridden by the caller.",
EventName = "BaseUrlOverrideIgnored")]
public static partial void BaseUrlOverrideIgnored(this ILogger logger);

[LoggerMessage(
EventId = 5,
Level = LogLevel.Warning,
Message = "Caller-supplied agent identity parameters were ignored on route '{RouteName}' because overrides are not allowed for it by configuration. To enable agent identity overrides, set 'Sidecar:AllowOverrides:{RouteName}' to true.",
EventName = "AgentIdentityOverridesIgnored")]
public static partial void AgentIdentityOverridesIgnored(this ILogger logger, string routeName);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"openapi": "3.0.1",
"openapi": "3.1.1",
"info": {
"title": "Microsoft.Identity.Web.Sidecar | v1",
"version": "1.0.0"
Expand Down Expand Up @@ -51,7 +51,7 @@
"Microsoft.Identity.Web.Sidecar"
],
"summary": "Get an authorization header for a configured downstream API.",
"description": "This endpoint will use the identity of the authenticated request to acquire an authorization header.Use dotted query parameters prefixed with 'optionsOverride.' to override call settings with respect to the configuration. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:GetAuthorizationHeader' (default: true). 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\nRepeat parameters like 'optionsOverride.Scopes' to add multiple scopes.",
"description": "This endpoint will use the identity of the authenticated request to acquire an authorization header. Use dotted query parameters prefixed with 'optionsOverride.' to override call settings with respect to the configuration. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:GetAuthorizationHeader' (default: true). Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\nRepeat parameters like 'optionsOverride.Scopes' to add multiple scopes.",
"operationId": "AuthorizationHeader",
"parameters": [
{
Expand Down Expand Up @@ -91,7 +91,6 @@
"name": "optionsOverride.Scopes",
"in": "query",
"description": "Repeatable. Each occurrence adds one scope. Example: optionsOverride.Scopes=User.Read",
"style": "form",
"schema": {
"type": "string"
}
Expand Down Expand Up @@ -156,9 +155,9 @@
{
"name": "optionsOverride.AcquireTokenOptions.ForceRefresh",
"in": "query",
"description": "boolean",
"description": "true = bypass token cache.",
"schema": {
"type": "true = bypass token cache."
"type": "boolean"
}
},
{
Expand Down Expand Up @@ -250,7 +249,7 @@
"Microsoft.Identity.Web.Sidecar"
],
"summary": "Get an authorization header for a configured downstream API using this configured client credentials.",
"description": "This endpoint will use the configured client credentials to acquire an authorization header.Use dotted query parameters prefixed with 'optionsOverride.' to override call settings with respect to the configuration. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:GetAuthorizationHeaderUnauthenticated' (default: false). 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\nRepeat parameters like 'optionsOverride.Scopes' to add multiple scopes.",
"description": "This endpoint will use the configured client credentials to acquire an authorization header. Use dotted query parameters prefixed with 'optionsOverride.' to override call settings with respect to the configuration. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:GetAuthorizationHeaderUnauthenticated' (default: false). Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\nRepeat parameters like 'optionsOverride.Scopes' to add multiple scopes.",
"operationId": "AuthorizationHeaderUnauthenticated",
"parameters": [
{
Expand Down Expand Up @@ -290,7 +289,6 @@
"name": "optionsOverride.Scopes",
"in": "query",
"description": "Repeatable. Each occurrence adds one scope. Example: optionsOverride.Scopes=User.Read",
"style": "form",
"schema": {
"type": "string"
}
Expand Down Expand Up @@ -355,9 +353,9 @@
{
"name": "optionsOverride.AcquireTokenOptions.ForceRefresh",
"in": "query",
"description": "boolean",
"description": "true = bypass token cache.",
"schema": {
"type": "true = bypass token cache."
"type": "boolean"
}
},
{
Expand Down Expand Up @@ -449,7 +447,7 @@
"Microsoft.Identity.Web.Sidecar"
],
"summary": "Invoke a configured downstream API through the sidecar using the authenticated identity.",
"description": "Override downstream call options using dotted query parameters prefixed with 'optionsOverride.'. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:CallDownstreamApi' (default: true). 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default",
"description": "Override downstream call options using dotted query parameters prefixed with 'optionsOverride.'. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:CallDownstreamApi' (default: true). Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default",
"operationId": "DownstreamApi",
"parameters": [
{
Expand Down Expand Up @@ -489,7 +487,6 @@
"name": "optionsOverride.Scopes",
"in": "query",
"description": "Repeatable. Each occurrence adds one scope. Example: optionsOverride.Scopes=User.Read",
"style": "form",
"schema": {
"type": "string"
}
Expand Down Expand Up @@ -554,9 +551,9 @@
{
"name": "optionsOverride.AcquireTokenOptions.ForceRefresh",
"in": "query",
"description": "boolean",
"description": "true = bypass token cache.",
"schema": {
"type": "true = bypass token cache."
"type": "boolean"
}
},
{
Expand Down Expand Up @@ -648,7 +645,7 @@
"Microsoft.Identity.Web.Sidecar"
],
"summary": "Invoke a configured downstream API through the sidecar using the configured client credentials.",
"description": "Override downstream call options using dotted query parameters prefixed with 'optionsOverride.'. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:CallDownstreamApiUnauthenticated' (default: false). 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default",
"description": "Override downstream call options using dotted query parameters prefixed with 'optionsOverride.'. Whether overrides are honoured is controlled by 'Sidecar:AllowOverrides:CallDownstreamApiUnauthenticated' (default: false). Agent identity parameters (AgentIdentity, AgentUsername, AgentUserId) are also subject to this setting. 'optionsOverride.BaseUrl' is always ignored. Examples:\n ?optionsOverride.Scopes=User.Read\n ?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read\n ?optionsOverride.AcquireTokenOptions.Tenant=GUID\n ?optionsOverride.RequestAppToken=true&optionsOverride.Scopes=https://graph.microsoft.com/.default",
"operationId": "DownstreamApiUnauthenticated",
"parameters": [
{
Expand Down Expand Up @@ -688,7 +685,6 @@
"name": "optionsOverride.Scopes",
"in": "query",
"description": "Repeatable. Each occurrence adds one scope. Example: optionsOverride.Scopes=User.Read",
"style": "form",
"schema": {
"type": "string"
}
Expand Down Expand Up @@ -753,9 +749,9 @@
{
"name": "optionsOverride.AcquireTokenOptions.ForceRefresh",
"in": "query",
"description": "boolean",
"description": "true = bypass token cache.",
"schema": {
"type": "true = bypass token cache."
"type": "boolean"
}
},
{
Expand Down Expand Up @@ -864,7 +860,11 @@
"type": "object",
"properties": {
"statusCode": {
"type": "integer",
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"integer",
"string"
],
"format": "int32"
},
"headers": {
Expand All @@ -877,8 +877,10 @@
}
},
"content": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
}
}
},
Expand All @@ -887,25 +889,37 @@
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"title": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"status": {
"type": "integer",
"format": "int32",
"nullable": true
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"null",
"integer",
"string"
],
"format": "int32"
},
"detail": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
},
"instance": {
"type": "string",
"nullable": true
"type": [
"null",
"string"
]
}
}
},
Expand Down
8 changes: 6 additions & 2 deletions src/Microsoft.Identity.Web.Sidecar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,17 @@ Complete documentation is provided [here](./OpenAPI/Microsoft.Identity.Web.Sidec

All token-acquisition endpoints accept dotted query parameters prefixed with `optionsOverride.`; they merge into a `DownstreamApis` profile through [`BindableDownstreamApiOptions`](Models/BindableDownstreamApiOptions.cs).

Whether overrides are honoured is controlled by the per-route `Sidecar:AllowOverrides` configuration flags. Authenticated routes allow overrides by default; unauthenticated routes ignore them unless the operator explicitly opts in. See [`SidecarOptions`](Configuration/SidecarOptions.cs) for details.

`optionsOverride.BaseUrl` is always ignored regardless of the override flag.

Examples:
- `?optionsOverride.Scopes=User.Read&optionsOverride.Scopes=Mail.Read`
- `?optionsOverride.RequestAppToken=true`
- `?optionsOverride.AcquireTokenOptions.Tenant=<tenant-guid>`
- `?optionsOverride.RelativePath=me/messages`

Agent impersonation hints:
Agent identity parameters are also subject to the per-route override flag:
- `AgentIdentity=<client-id>`
- `AgentUsername=upn@contoso.com`
- `AgentUserId=<oid>`
Expand All @@ -148,5 +152,5 @@ Agent impersonation hints:
| Authentication & authorization | [`Program`](Program.cs) wires `AddMicrosoftIdentityWebApi`, optional scope enforcement, and agent identity overrides. |
| Endpoints | [`ValidateRequestEndpoints`](Endpoints/ValidateRequestEndpoints.cs), [`AuthorizationHeaderEndpoint`](Endpoints/AuthorizationHeaderEndpoint.cs), and [`DownstreamApiEndpoint`](Endpoints/DownstreamApiEndpoint.cs). |
| Downstream API | [`BindableDownstreamApiOptions`](Models/BindableDownstreamApiOptions.cs) merges per-request overrides into per call `DownstreamApis` configuration. |
| Agent Identities | [`AgentOverrides`](AgentOverrides.cs) binds agent identity, userPrincipalName, or user object ID when present. |
| Agent Identities | [`AgentOverrides`](AgentOverrides.cs) binds agent identity, userPrincipalName, or user object ID when present and allowed by the per-route override flag. |

Loading
Loading