Skip to content

.NET: AuthN & AuthZ sample with asp.net service and web client#4354

Open
westey-m wants to merge 4 commits intomicrosoft:mainfrom
westey-m:client-server-auth-sample
Open

.NET: AuthN & AuthZ sample with asp.net service and web client#4354
westey-m wants to merge 4 commits intomicrosoft:mainfrom
westey-m:client-server-auth-sample

Conversation

@westey-m
Copy link
Contributor

Motivation and Context

#1488

Users are regularly asking about how to access user information in tools and how to authorize tools. This sample shows an example of how authorization and user access could be done from tools in an agent.

Using Keycloak as the auth provider, so that the sample can be run without any external dependencies, but it can easily be swapped out for another auth provider.

Description

  • Add a sample with three components that are run via docker compose: Web, Service, Auth Provider
  • The service exposes a chat interface that is only available to users with the right scopes
  • The service uses an agent that uses tools that need to store a TODO list under the active user's user id.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings February 27, 2026 18:44
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation .NET labels Feb 27, 2026
@github-actions github-actions bot changed the title AuthN & AuthZ sample with asp.net service and web client .NET: AuthN & AuthZ sample with asp.net service and web client Feb 27, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a comprehensive authentication and authorization sample demonstrating how to secure an AI agent REST API using OAuth 2.0 / OpenID Connect standards. The sample addresses issue #1488 by showcasing dependency injection, user context access in tools, JWT Bearer authentication, and policy-based authorization.

Changes:

  • Added a three-component sample (WebClient, AgentService, Keycloak) orchestrated with Docker Compose
  • Demonstrates accessing user identity in agent tools via scoped IUserContext service
  • Includes GitHub Codespaces support with auto-detection and configuration
  • Shows JWT Bearer token validation and scope-based authorization policies

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
docker-compose.yml Orchestrates Keycloak, AgentService, and WebClient with health checks and Codespaces support
keycloak/dev-realm.json Pre-configured Keycloak realm with test users, scopes, and client definitions
keycloak/setup-redirect-uris.sh Auto-configures Codespaces redirect URIs for OIDC flows
README.md Comprehensive documentation for setup, usage, and key concepts
AuthClientServer.AgentService/* Minimal API with JWT authentication, authorization policies, and DI-based agent
AuthClientServer.WebClient/* Razor Pages app with OIDC login, token forwarding, and chat UI
UserContext.cs Scoped service for accessing current user identity from JWT claims
TodoService.cs Per-user TODO list demonstrating user-aware tool implementation
Dockerfiles Multi-stage builds with proper CPM support via Directory.Packages.props
Directory.Packages.props Added JWT Bearer and OpenIdConnect package versions
agent-framework-dotnet.slnx Solution file updated to include new projects

### Option 1: Docker Compose (Recommended)

```bash
cd samples/AuthClientServer
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path shown here is incomplete. Users following this command from the repository root will encounter an error. Change this to: cd dotnet/samples/05-end-to-end/AuthClientServer

Suggested change
cd samples/AuthClientServer
cd dotnet/samples/05-end-to-end/AuthClientServer

Copilot uses AI. Check for mistakes.
CLIENT_UUID=$(curl -sf "$KEYCLOAK_URL/admin/realms/dev/clients?clientId=web-client" \
-H "Authorization: Bearer $TOKEN" \
| sed -n 's/.*"id":"\([^"]*\)".*/\1/p')

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling for CLIENT_UUID extraction. If the curl command fails or the client is not found, CLIENT_UUID will be empty, causing the subsequent PUT request to target an invalid endpoint. Add validation after line 35:

if [ -z "$CLIENT_UUID" ]; then
    echo "ERROR: Failed to find web-client UUID" >&2
    exit 1
fi
Suggested change
if [ -z "$CLIENT_UUID" ]; then
echo "ERROR: Failed to find web-client UUID" >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +77
// ---------------------------------------------------------------------------
// CORS: allow the WebClient origin
// ---------------------------------------------------------------------------
builder.Services.AddCors(options =>
options.AddDefaultPolicy(policy =>
policy.WithOrigins("http://localhost:8080")
.AllowAnyHeader()
.AllowAnyMethod()));
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CORS configuration is unnecessary and potentially misleading in this sample. The WebClient calls the AgentService through server-side code (in Chat.cshtml.cs), not from browser JavaScript, so CORS is never checked. Additionally, if CORS were needed, this configuration only allows http://localhost:8080, which would not work in GitHub Codespaces where the actual origin would be the Codespaces tunnel URL. Consider removing this CORS configuration entirely to avoid confusion.

Copilot uses AI. Check for mistakes.

WebApplication app = builder.Build();

app.UseCors();
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This middleware is unnecessary since CORS is not needed for this sample. The WebClient makes server-side HTTP requests to the AgentService, not browser-based requests. Remove this line along with the CORS configuration above (lines 73-77).

Suggested change
app.UseCors();

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name of the project was AuthClientServer but the name of the Server project is AgentService and the Client WebClient.

Ideally suggest renaming the the project to be more clear that this is actually a Minimal Api approach (not MVC) or having both Server.MinimalApi and a Server.Mvc within the same sample for all the tastes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the client might suggest adding Razor in the naming to be clear what is the tech chosen, worth adding a Blazor and a React.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation .NET

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants