Last active
July 29, 2025 15:46
-
-
Save rido-min/d0ed232def872e4fbb50b0e781e97288 to your computer and use it in GitHub Desktop.
zero-config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Copyright (c) Microsoft Corporation. All rights reserved. | |
| // Licensed under the MIT License. | |
| using Microsoft.Agents.Authentication; | |
| using Microsoft.Agents.Authentication.Model; | |
| using Microsoft.Agents.Authentication.Msal; | |
| using Microsoft.Agents.Authentication.Msal.Interfaces; | |
| using Microsoft.Agents.Authentication.Msal.Model; | |
| using Microsoft.Agents.Builder; | |
| using Microsoft.Agents.Builder.App; | |
| using Microsoft.Agents.Builder.App.UserAuth; | |
| using Microsoft.Agents.Builder.Compat; | |
| using Microsoft.Agents.Builder.UserAuth; | |
| using Microsoft.Agents.Builder.UserAuth.TokenService; | |
| using Microsoft.Agents.Hosting.AspNetCore; | |
| using Microsoft.Agents.Storage; | |
| using Microsoft.Agents.Storage.Transcript; | |
| using Microsoft.AspNetCore.Mvc.Formatters; | |
| using static Microsoft.Agents.AspNetAuthentication.AspNetExtensions; | |
| static void DotEnvLoad(string filePath) | |
| { | |
| if (!File.Exists(filePath)) | |
| return; | |
| foreach (var line in File.ReadAllLines(filePath)) | |
| { | |
| var parts = line.Split( | |
| '=', | |
| StringSplitOptions.RemoveEmptyEntries); | |
| if (parts.Length != 2) | |
| continue; | |
| Environment.SetEnvironmentVariable(parts[0], parts[1]); | |
| } | |
| } | |
| DotEnvLoad(Path.Combine(Directory.GetCurrentDirectory(), ".env")); | |
| var builder = WebApplication.CreateBuilder(args); | |
| // builder.Services.AddHttpClient(); | |
| builder.Services.AddAuthorization(); | |
| builder.Services.AddSingleton<IStorage, MemoryStorage>(); | |
| builder.Services.AddAgentAspNetAuthentication(new TokenValidationOptions() | |
| { | |
| TenantId = Environment.GetEnvironmentVariable("tenantId")!, | |
| Audiences = new List<string> { Environment.GetEnvironmentVariable("clientId")! }, | |
| }); | |
| builder.Services.AddSingleton<IConnections>(sp => | |
| { | |
| return new ConfigurationConnections( | |
| new Dictionary<string, IAccessTokenProvider> { | |
| { | |
| "ServiceConnection", | |
| new MsalAuth(sp, new ConnectionSettings() | |
| { | |
| AuthType = AuthTypes.ClientSecret, | |
| ClientSecret = Environment.GetEnvironmentVariable("clientSecret"), | |
| Authority = $"https://login.microsoftonline.com/{Environment.GetEnvironmentVariable("tenantId")}", | |
| ClientId = Environment.GetEnvironmentVariable("clientId"), | |
| Scopes = [$"{AuthenticationConstants.BotFrameworkScope}/.default"] // should add/change a constant for this. | |
| }) | |
| } | |
| }, | |
| [ | |
| new ConnectionMapItem() { ServiceUrl = "*", Connection = "ServiceConnection" } | |
| ] | |
| ); | |
| }); | |
| builder.Services.AddSingleton(sp => | |
| { | |
| var storage = sp.GetService<IStorage>(); | |
| var connections = sp.GetService<IConnections>(); | |
| // List of OAuth Handlers (clearer than doing it inline below) | |
| IUserAuthorization[] handlers = [ | |
| new AzureBotUserAuthorization( | |
| "graph", | |
| storage!, | |
| connections!, | |
| new OAuthSettings() | |
| { | |
| AzureBotOAuthConnectionName = "SSOADv2", | |
| Title = "SigIn for Sample", | |
| Text = "Please sign in and send the 6-digit code" | |
| } | |
| ), | |
| new AzureBotUserAuthorization( | |
| "github", | |
| storage!, | |
| connections!, | |
| new OAuthSettings() | |
| { | |
| AzureBotOAuthConnectionName = "GH", | |
| Title = "SigIn for Me", | |
| Text = "Please sign in and send the 6-digit code" | |
| } | |
| ) | |
| ]; | |
| return new AgentApplicationOptions(storage!) | |
| { | |
| StartTypingTimer = true, | |
| NormalizeMentions = false, | |
| RemoveRecipientMention = false, | |
| Adapter = sp.GetService<IChannelAdapter>(), | |
| UserAuthorization = new(connections!, handlers) | |
| { | |
| DefaultHandlerName = "graph", | |
| AutoSignIn = UserAuthorizationOptions.AutoSignInOnForAny, | |
| } | |
| }; | |
| }); | |
| builder.Services.AddSingleton<IChannelServiceClientFactory, RestChannelServiceClientFactory>(); | |
| builder.Services.AddCloudAdapter(); | |
| builder.Services.AddTransient<IAgent, AuthAgent>(); | |
| // And just for fun register a compat TranscriptLogger (because I haven't submitted the AgentApplication friendly version) | |
| builder.Services.AddSingleton<Microsoft.Agents.Builder.IMiddleware[]>([ | |
| new TranscriptLoggerMiddleware(new FileTranscriptLogger()) | |
| ]); | |
| WebApplication app = builder.Build(); | |
| app.MapGet("/", () => "Microsoft Agents SDK Sample"); | |
| app.UseAuthorization(); | |
| // This receives incoming messages from Azure Bot Service or other SDK Agents | |
| app.MapPost("/api/messages", async (HttpRequest request, HttpResponse response, IAgentHttpAdapter adapter, IAgent agent, CancellationToken cancellationToken) => | |
| { | |
| await adapter.ProcessAsync(request, response, agent, cancellationToken); | |
| }).RequireAuthorization(); | |
| app.Run(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment