diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 16efe2a..248c1f8 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -206,3 +206,27 @@ After upgrading, use VS Code's **Problems panel** (or `get_errors` tool) to conf - `body: null` may not be allowed (use `body: ""` instead) - New required properties may be added - Property types may become stricter + +## Common Mistakes to Avoid + +### PRESET Metadata +- **PRESET should be "No"** for most samples +- Only set `"PRESET": "Yes"` if the sample is **reusable for other purposes** (e.g., a generic configuration that developers can apply to their own APIs) +- Having a `devproxyrc.json` config file does NOT automatically make it a preset + +### Startup Commands +- `.devproxy/devproxyrc.json` is a **default path** that Dev Proxy looks for automatically +- When config is in `.devproxy/devproxyrc.json`, the startup command should just be `devproxy` (no `--config-file` needed) +- Only use `--config-file` when the config file is in a non-default location or has a non-default name + +### Updating Dates +- When updating sample dates, **always update both files**: + - `assets/sample.json`: Update `updateDateTime` field + - `README.md`: Update the version history table with the new date +- Dates must stay in sync between these two files +- **Pre-release updates** (sample not yet merged to main): + - Update both `creationDateTime` and `updateDateTime` in `sample.json` + - Update the v1.0 date in the README version history table +- **Post-release updates** (sample already in main): + - Only update `updateDateTime` in `sample.json` + - Add a new version entry (e.g., 1.1) to the README version history table diff --git a/samples/api-key-protected-mock/.devproxy/devproxyrc.json b/samples/api-key-protected-mock/.devproxy/devproxyrc.json new file mode 100644 index 0000000..6955b13 --- /dev/null +++ b/samples/api-key-protected-mock/.devproxy/devproxyrc.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/rc.schema.json", + "plugins": [ + { + "name": "AuthPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", + "configSection": "auth" + }, + { + "name": "MockResponsePlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", + "configSection": "mockResponsePlugin" + } + ], + "urlsToWatch": [ + "https://api.contoso.com/*" + ], + "auth": { + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/authplugin.schema.json", + "type": "apiKey", + "apiKey": { + "parameters": [ + { + "in": "header", + "name": "x-api-key" + }, + { + "in": "query", + "name": "code" + }, + { + "in": "cookie", + "name": "api_key" + } + ], + "allowedKeys": [ + "secret-key-123", + "dev-key-456" + ] + } + }, + "mockResponsePlugin": { + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json", + "mocksFile": "mocks.json" + } +} diff --git a/samples/api-key-protected-mock/.devproxy/mocks.json b/samples/api-key-protected-mock/.devproxy/mocks.json new file mode 100644 index 0000000..f567bfa --- /dev/null +++ b/samples/api-key-protected-mock/.devproxy/mocks.json @@ -0,0 +1,148 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.mocksfile.schema.json", + "mocks": [ + { + "request": { + "url": "https://api.contoso.com/items", + "method": "GET" + }, + "response": { + "statusCode": 200, + "headers": [ + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "x-powered-by", + "value": "Dev Proxy" + }, + { + "name": "x-mocked-by", + "value": "Dev Proxy MockResponsePlugin" + } + ], + "body": [ + { + "id": 1, + "name": "Item 1", + "description": "First item in the collection" + }, + { + "id": 2, + "name": "Item 2", + "description": "Second item in the collection" + }, + { + "id": 3, + "name": "Item 3", + "description": "Third item in the collection" + } + ] + } + }, + { + "request": { + "url": "https://api.contoso.com/items/*", + "method": "GET" + }, + "response": { + "statusCode": 200, + "headers": [ + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "x-powered-by", + "value": "Dev Proxy" + }, + { + "name": "x-mocked-by", + "value": "Dev Proxy MockResponsePlugin" + } + ], + "body": { + "id": 1, + "name": "Item 1", + "description": "First item in the collection" + } + } + }, + { + "request": { + "url": "https://api.contoso.com/items", + "method": "POST" + }, + "response": { + "statusCode": 201, + "headers": [ + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "x-powered-by", + "value": "Dev Proxy" + }, + { + "name": "x-mocked-by", + "value": "Dev Proxy MockResponsePlugin" + } + ], + "body": { + "id": 4, + "name": "New Item", + "description": "Newly created item" + } + } + }, + { + "request": { + "url": "https://api.contoso.com/items/*", + "method": "PUT" + }, + "response": { + "statusCode": 200, + "headers": [ + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "x-powered-by", + "value": "Dev Proxy" + }, + { + "name": "x-mocked-by", + "value": "Dev Proxy MockResponsePlugin" + } + ], + "body": { + "id": 1, + "name": "Updated Item", + "description": "Updated item description" + } + } + }, + { + "request": { + "url": "https://api.contoso.com/items/*", + "method": "DELETE" + }, + "response": { + "statusCode": 204, + "headers": [ + { + "name": "x-powered-by", + "value": "Dev Proxy" + }, + { + "name": "x-mocked-by", + "value": "Dev Proxy MockResponsePlugin" + } + ] + } + } + ] +} diff --git a/samples/api-key-protected-mock/README.md b/samples/api-key-protected-mock/README.md new file mode 100644 index 0000000..3e12ee3 --- /dev/null +++ b/samples/api-key-protected-mock/README.md @@ -0,0 +1,121 @@ +# Simulating API key authentication + +## Summary + +This sample demonstrates how to simulate API key authentication for mock APIs using Dev Proxy. The AuthPlugin validates API keys in header, query parameter, or cookie, while the MockResponsePlugin provides the API responses. This is useful for testing API key authentication flows without a real backend, such as Azure Functions, API Gateway integrations, and other services that use API keys for authentication. + +![Dev Proxy simulating API key authentication](assets/screenshot.png) + +## Compatibility + +![Dev Proxy v2.0.0](https://aka.ms/devproxy/badge/v2.0.0) + +## Contributors + +* [Waldek Mastykarz](https://github.com/waldekmastykarz) + +## Version history + +Version|Date|Comments +-------|----|-------- +1.0|January 18, 2026|Initial release + +## Minimal path to awesome + +* Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/proxy-samples/tree/main/samples/api-key-protected-mock) then unzip it) +* Start Dev Proxy: `devproxy` +* Test the API key authentication by making requests: + +**With valid API key in header (should return 200):** +```bash +curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "x-api-key: secret-key-123" +``` + +**With valid API key in query parameter (should return 200):** +```bash +curl -ikx http://127.0.0.1:8000 "https://api.contoso.com/items?code=dev-key-456" +``` + +**With valid API key in cookie (should return 200):** +```bash +curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "Cookie: api_key=secret-key-123" +``` + +**Without API key (should return 401 Unauthorized):** +```bash +curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items +``` + +**With invalid API key (should return 401 Unauthorized):** +```bash +curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "x-api-key: invalid-key" +``` + +## Features + +This sample configures API key authentication that accepts keys in multiple locations: + +**Supported API Key Locations:** +* `header` - Pass the API key in the `x-api-key` header +* `query` - Pass the API key as the `code` query parameter +* `cookie` - Pass the API key in the `api_key` cookie + +**Allowed API Keys:** +* `secret-key-123` - Primary API key for testing +* `dev-key-456` - Secondary API key for development + +**Mock API Endpoints:** +* `GET /items` - List all items +* `GET /items/{id}` - Get a specific item +* `POST /items` - Create a new item +* `PUT /items/{id}` - Update an item +* `DELETE /items/{id}` - Delete an item + +Using this sample you can use Dev Proxy to: + +* Test API key authentication flows without a real backend +* Simulate Azure Functions or API Gateway authentication +* Validate client applications properly include API keys in requests +* Verify applications handle 401 Unauthorized responses correctly +* Test different API key transmission methods (header, query, cookie) + +## Configuration + +The sample uses the following configuration to enable API key authentication: + +```json +{ + "auth": { + "type": "apiKey", + "apiKey": { + "parameters": [ + { "in": "header", "name": "x-api-key" }, + { "in": "query", "name": "code" }, + { "in": "cookie", "name": "api_key" } + ], + "allowedKeys": ["secret-key-123", "dev-key-456"] + } + } +} +``` + +You can customize the configuration by: +* Adding or removing parameter locations (header, query, cookie) +* Changing parameter names to match your API's requirements +* Adding or removing allowed API keys + +## Help + +We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues. + +You can try looking at [issues related to this sample](https://github.com/pnp/proxy-samples/issues?q=label%3A%22sample%3A%20api-key-protected-mock%22) to see if anybody else is having the same issues. + +If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/proxy-samples/issues/new). + +Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/proxy-samples/issues/new). + +## Disclaimer + +**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +![](https://m365-visitor-stats.azurewebsites.net/SamplesGallery/pnp-devproxy-api-key-protected-mock) diff --git a/samples/api-key-protected-mock/assets/sample.json b/samples/api-key-protected-mock/assets/sample.json new file mode 100644 index 0000000..c4ae5d8 --- /dev/null +++ b/samples/api-key-protected-mock/assets/sample.json @@ -0,0 +1,72 @@ +[ + { + "name": "pnp-devproxy-api-key-protected-mock", + "source": "pnp", + "title": "Simulating API key authentication", + "shortDescription": "Demonstrates how to simulate API key authentication for mock APIs using Dev Proxy with AuthPlugin and MockResponsePlugin.", + "url": "https://github.com/pnp/proxy-samples/tree/main/samples/api-key-protected-mock", + "downloadUrl": "https://pnp.github.io/download-partial/?url=https://github.com/pnp/proxy-samples/tree/main/samples/api-key-protected-mock", + "longDescription": [ + "Demonstrates how to simulate API key authentication for mock APIs using Dev Proxy with AuthPlugin and MockResponsePlugin." + ], + "creationDateTime": "2026-01-18", + "updateDateTime": "2026-01-18", + "products": [ + "Dev Proxy" + ], + "metadata": [ + { + "key": "SAMPLE ID", + "value": "api-key-protected-mock" + }, + { + "key": "PRESET", + "value": "No" + }, + { + "key": "MOCKS", + "value": "Yes" + }, + { + "key": "PLUGIN", + "value": "No" + }, + { + "key": "PROXY VERSION", + "value": "v2.0.0" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://github.com/pnp/proxy-samples/raw/main/samples/api-key-protected-mock/assets/screenshot.png", + "alt": "Dev Proxy simulating API key authentication" + } + ], + "authors": [ + { + "gitHubAccount": "waldekmastykarz", + "pictureUrl": "https://github.com/waldekmastykarz.png", + "name": "Waldek Mastykarz" + } + ], + "references": [ + { + "name": "Get started with the Dev Proxy", + "description": "The tutorial will introduce you to the Dev Proxy and show you how to use its features.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/get-started" + }, + { + "name": "AuthPlugin documentation", + "description": "The documentation of the AuthPlugin for the Dev Proxy.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/technical-reference/authplugin" + }, + { + "name": "MockResponsePlugin documentation", + "description": "The documentation of the MockResponsePlugin for the Dev Proxy.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/technical-reference/mockresponseplugin" + } + ] + } +] diff --git a/samples/api-key-protected-mock/assets/screenshot.png b/samples/api-key-protected-mock/assets/screenshot.png new file mode 100644 index 0000000..d5a53b1 Binary files /dev/null and b/samples/api-key-protected-mock/assets/screenshot.png differ