microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
cg/silent-401

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/samples/OAuthFlowBot/Program.cs

211lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4// This sample demonstrates how to use OAuthFlow with two OAuth connections:
5// - GraphConnection: Microsoft Graph (Azure AD v2) for user profile and calendar
6// - GitHubConnection: GitHub for repositories
7//
8// Azure Bot resource must have two OAuth connection settings configured:
9// | Connection name | Provider | Scopes |
10// |-------------------|--------------|---------------------------|
11// | GraphConnection | Azure AD v2 | User.Read Calendars.Read |
12// | GitHubConnection | GitHub | repo read:user |
13
14using Microsoft.Teams.Apps;
15using Microsoft.Teams.Apps.Handlers;
16using Microsoft.Teams.Apps.OAuth;
17using Microsoft.Teams.Apps.Schema;
18
19WebApplicationBuilder webAppBuilder = WebApplication.CreateSlimBuilder(args);
20
21// Configure OAuth flows at the DI level -- card text is set once here
22webAppBuilder.Services.AddTeamsBotApplication(options =>
23{
24 options.AddOAuthFlow("sso", o =>
25 {
26 o.OAuthCardText = "Sign in to your Microsoft account";
27 o.SignInButtonText = "Sign In to Graph";
28 });
29 options.AddOAuthFlow("gh", o =>
30 {
31 o.OAuthCardText = "Sign in to your GitHub account";
32 o.SignInButtonText = "Sign In to GitHub";
33 });
34});
35
36WebApplication webApp = webAppBuilder.Build();
37
38TeamsBotApplication bot = webApp.UseTeamsBotApplication();
39
40// ==================== OAUTH FLOW SETUP ====================
41
42// Get the pre-registered flows and attach callbacks
43OAuthFlow graphAuth = bot.GetOAuthFlow("sso");
44OAuthFlow githubAuth = bot.GetOAuthFlow("gh");
45
46graphAuth.OnSignInComplete(async (context, tokenResponse, ct) =>
47{
48 await context.SendActivityAsync($"User {context.Activity.From?.Name} connected to Microsoft Graph ({tokenResponse.ConnectionName})!", ct);
49});
50
51graphAuth.OnSignInFailure(async (context, failure, ct) =>
52{
53 await context.SendActivityAsync($"User {context.Activity.From?.Name} failed to connect to Microsoft Graph. {failure?.Message}", ct);
54});
55
56githubAuth.OnSignInComplete(async (context, tokenResponse, ct) =>
57{
58 await context.SendActivityAsync($"User {context.Activity.From?.Name} connected to GitHub ({tokenResponse.ConnectionName})!", ct);
59});
60
61githubAuth.OnSignInFailure(async (context, failure, ct) =>
62{
63 await context.SendActivityAsync($"User {context.Activity.From?.Name} failed to connect to GitHub. {failure?.Message}", ct);
64});
65
66// ==================== MESSAGE HANDLERS ====================
67
68bot.OnMessage("(?i)^help$", async (context, ct) =>
69{
70 string helpText = """
71 **OAuthFlow Bot** - Multi-connection OAuth sample
72
73 Commands:
74 - `login` - Sign in to all connections
75 - `login graph` - Sign in to Microsoft Graph
76 - `login github` - Sign in to GitHub
77 - `status` - Show OAuth connection status
78 - `my ad user` - Get your Azure AD user (requires Graph)
79 - `my gh user` - Get your GitHub user (requires GitHub)
80 - `logout` - Sign out from all connections
81 - `logout graph` - Sign out from Graph only
82 - `logout github` - Sign out from GitHub only
83 - `help` - Show this message
84 """;
85
86 await context.SendActivityAsync(
87 new MessageActivity(helpText) { TextFormat = TextFormats.Markdown }, ct);
88});
89
90bot.OnMessage("(?i)^login$", async (context, ct) =>
91{
92 string? tokenGitHub = await githubAuth.SignInAsync(context, ct);
93 string? tokenGraph = await graphAuth.SignInAsync(context, ct);
94 if (tokenGraph is not null)
95 {
96 await context.SendActivityAsync("Already signed in to Graph.", ct);
97 }
98
99 if (tokenGitHub is not null)
100 {
101 await context.SendActivityAsync("Already signed in to GitHub.", ct);
102 }
103
104});
105
106bot.OnMessage("(?i)^login graph$", async (context, ct) =>
107{
108 string? tokenGraph = await graphAuth.SignInAsync(context, ct);
109 if (tokenGraph is not null)
110 {
111 await context.SendActivityAsync("Already signed in to Graph.", ct);
112 }
113 // else: OAuthCard sent, SSO in progress
114});
115
116bot.OnMessage("(?i)^login github$", async (context, ct) =>
117{
118 string? tokenGitHub = await githubAuth.SignInAsync(context, ct);
119 if (tokenGitHub is not null)
120 {
121 await context.SendActivityAsync("Already signed in to GitHub.", ct);
122 }
123});
124
125bot.OnMessage("(?i)^status$", async (context, ct) =>
126{
127 // GetConnectionStatusAsync returns ALL connections -- no names needed
128 var statuses = await graphAuth.GetConnectionStatusAsync(context, ct);
129 var lines = statuses.Select(s =>
130 $"- **{s.ConnectionName}** ({s.ServiceProviderDisplayName}): " +
131 $"{(s.HasToken == true ? "✅ connected" : "❌ not connected")}");
132
133 await context.SendActivityAsync(
134 new MessageActivity($"OAuth connections for {context.Activity.From?.Name} :\n" + string.Join("\n", lines))
135 {
136 TextFormat = TextFormats.Markdown
137 }, ct);
138});
139
140bot.OnMessage("(?i)^my ad user", async (context, ct) =>
141{
142 string? token = await graphAuth.SignInAsync(context, ct);
143 if (token is null) return;
144
145 using var http = new HttpClient();
146 http.DefaultRequestHeaders.Authorization = new("Bearer", token);
147
148 try
149 {
150 string response = await http.GetStringAsync(
151 "https://graph.microsoft.com/v1.0/me", ct);
152 await context.SendActivityAsync($"Your Azure AD user :\n```json\n{response}\n```", ct);
153 }
154 catch (HttpRequestException ex)
155 {
156 await context.SendActivityAsync($"Failed to fetch Azure AD user: {ex.Message}", ct);
157 }
158});
159
160bot.OnMessage("(?i)^my gh user$", async (context, ct) =>
161{
162 string? token = await githubAuth.SignInAsync(context, ct);
163 if (token is null) return;
164
165 using var http = new HttpClient();
166 http.DefaultRequestHeaders.Authorization = new("Bearer", token);
167 http.DefaultRequestHeaders.UserAgent.ParseAdd("TeamsBot/1.0");
168
169 try
170 {
171 string response = await http.GetStringAsync(
172 "https://api.github.com/user", ct);
173 await context.SendActivityAsync($"Your GitHub user :\n```json\n{response}\n```", ct);
174 }
175 catch (HttpRequestException ex)
176 {
177 await context.SendActivityAsync($"Failed to fetch GitHub user: {ex.Message}", ct);
178 }
179});
180
181bot.OnMessage("(?i)^logout$", async (context, ct) =>
182{
183 await graphAuth.SignOutAsync(context, ct);
184 await githubAuth.SignOutAsync(context, ct);
185 await context.SendActivityAsync("Signed out from all services.", ct);
186});
187
188bot.OnMessage("(?i)^logout graph$", async (context, ct) =>
189{
190 await graphAuth.SignOutAsync(context, ct);
191 await context.SendActivityAsync("Signed out from Graph.", ct);
192});
193
194bot.OnMessage("(?i)^logout github$", async (context, ct) =>
195{
196 await githubAuth.SignOutAsync(context, ct);
197 await context.SendActivityAsync("Signed out from GitHub.", ct);
198});
199
200// ==================== INSTALL HANDLER ====================
201
202bot.OnInstall(async (context, ct) =>
203{
204 await context.SendActivityAsync(
205 new MessageActivity("Welcome to the **OAuthFlow Bot**! Type `help` to see available commands.")
206 {
207 TextFormat = TextFormats.Markdown
208 }, ct);
209});
210
211webApp.Run();
212