-
Notifications
You must be signed in to change notification settings - Fork 65
Description
Version
What package version of the SDK are you using.
- Nuget package version: 1.2.41
Describe the bug
Single sign-on (SSO) does not work reliably when using BlobStorage as the storage provider. Users intermittently fail to authenticate or lose their SSO session, which disrupts expected functionality.
To Reproduce
Create Microsoft Entra app registration with delegated API permissions (e.g Microsoft Graph User.Read), client secret, create Application URI, scope and configure pre authorised applications.
{
"id": "911a6db0-ce69-416f-9a29-d240453fdd8b",
"appId": "ce3b5e58-03cc-496b-b223-51dad4500654",
"displayName": "my-agent-api-local",
"identifierUris": [
"api://botid-92134b16-0928-4141-8f5b-809c26bd1a7c"
],
"signInAudience": "AzureADMyOrg",
"api": {
"requestedAccessTokenVersion": 2,
"oauth2PermissionScopes": [
{
"adminConsentDescription": "Allows the agent to call the app's web APIs as the current user.",
"adminConsentDisplayName": "Agent can access app's web APIs",
"id": "d84d75c1-ef4b-43a1-9c5f-592f75991874",
"isEnabled": true,
"type": "User",
"userConsentDescription": "Enable the agent to call this app's web APIs with the same rights that you have",
"userConsentDisplayName": "Agent can access app's web APIs and make requests on your behalf",
"value": "access_as_user"
}
],
"preAuthorizedApplications": [
{
"appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
"delegatedPermissionIds": [
"d84d75c1-ef4b-43a1-9c5f-592f75991874"
]
},
{
"appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346",
"delegatedPermissionIds": [
"d84d75c1-ef4b-43a1-9c5f-592f75991874"
]
},
{
"appId": "4765445b-32c6-49b0-83e6-1d93765276ca",
"delegatedPermissionIds": [
"d84d75c1-ef4b-43a1-9c5f-592f75991874"
]
},
{
"appId": "0ec893e0-5785-4de6-99da-4ed124e5296c",
"delegatedPermissionIds": [
"d84d75c1-ef4b-43a1-9c5f-592f75991874"
]
},
{
"appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c",
"delegatedPermissionIds": [
"d84d75c1-ef4b-43a1-9c5f-592f75991874"
]
},
{
"appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3",
"delegatedPermissionIds": [
"d84d75c1-ef4b-43a1-9c5f-592f75991874"
]
},
{
"appId": "27922004-5251-4030-b22d-91ecd9a37ea4",
"delegatedPermissionIds": [
"d84d75c1-ef4b-43a1-9c5f-592f75991874"
]
}
]
},
"info": {},
"optionalClaims": {},
"publicClient": {
"redirectUris": []
},
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "14dad69e-099b-42c9-810b-d002981feec1",
"type": "Scope"
},
{
"id": "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0",
"type": "Scope"
},
{
"id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
"type": "Scope"
},
{
"id": "37f7f235-527c-4136-accd-4a02d197296e",
"type": "Scope"
}
]
}
],
"web": {
"redirectUris": [
"https://token.botframework.com/.auth/web/redirect"
],
"implicitGrantSettings": {}
},
"spa": {
"redirectUris": []
}
}Add webApplicationInfo and update validDomains array to app manifest.
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.22/MicrosoftTeams.schema.json",
"manifestVersion": "1.22",
"version": "1.0.8",
"id": "${{TEAMS_APP_ID}}",
"developer": {
"name": "Teams App, Inc.",
"websiteUrl": "https://www.example.com",
"privacyUrl": "https://www.example.com/privacy",
"termsOfUseUrl": "https://www.example.com/termofuse"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "${{APP_DISPLAY_NAME}} ${{APP_NAME_SUFFIX}}",
"full": "full name for ${{APP_DISPLAY_NAME}}"
},
"description": {
"short": "Short description of ${{APP_DISPLAY_NAME}}",
"full": "Full description of ${{APP_DISPLAY_NAME}}"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "${{BOT_ID}}",
"scopes": [ "copilot" ],
"supportsFiles": false,
"isNotificationOnly": false,
"commandLists": [
{
"scopes": [ "copilot" ],
"commands": [
{
"title": "Say hi to the bot",
"description": "Hi"
}
]
}
]
}
],
"copilotAgents": {
"customEngineAgents": [
{
"id": "${{BOT_ID}}",
"type": "bot"
}
]
},
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"token.botframework.com"
],
"webApplicationInfo": {
"id": "${{ENTRA_API_ID}}",
"resource": "api://botid-${{BOT_ID}}"
}
}Create connection setting on bot service.
resource botServiceAccessTokenConnection 'Microsoft.BotService/botServices/connections@2022-09-15' = {
parent: botService
name: 'AccessToken'
location: 'global'
properties: {
serviceProviderDisplayName: 'Azure Active Directory v2'
serviceProviderId: '30dd229c-58e3-4a48-bdfd-91ec48eb906c'
clientId: apiEntraAppClientId
clientSecret: apiEntraAppClientSecret
scopes: 'offline_access User.Read'
parameters: [
{
key: 'tenantID'
value: apiEntraAppTenantId
}
{
key: 'tokenExchangeUrl'
value: 'api://botid-${botEntraAppClientId}'
}
]
}
}Create a custom engine agent using Agents SDK, implement BlobStorage for state storage persistence.
builder.Services.AddSingleton<IStorage>((sp) => {
var containerName = builder.Configuration["BlobsStorageOptions:ContainerName"] ?? "state";
if (builder.Environment.IsDevelopment())
{
// Use Azurite for local development storage
return new BlobsStorage("UseDevelopmentStorage=true", containerName);
}
else
{
// Use managed identity for production
var storageAccountName = builder.Configuration["BlobsStorageOptions:StorageAccountName"];
return new BlobsStorage(
new Uri($"https://{storageAccountName}.blob.core.windows.net/{containerName}"),
new DefaultAzureCredential()
);
}
});Configure OAuth settings in appsettings.json file, with AutoSignIn set to false
{
"AgentApplication": {
"StartTypingTimer": false,
"RemoveRecipientMention": false,
"NormalizeMentions": false,
"UserAuthorization": {
"DefaultHandlerName": "me",
"AutoSignin": false,
"Handlers": {
"me": {
"Settings": {
"AzureBotOAuthConnectionName": "AccessToken",
"Title": "Sign in",
"Text": "Sign in"
}
},
"auto": {
"Settings": {
"AzureBotOAuthConnectionName": "UserToken",
"Title": "Sign in",
"Text": "Sign in"
}
}
}
}
}
}In CEA code, register a message handler in the constructor and configure autoSignInHandlers array.
OnActivity(ActivityTypes.Message, OnMessageAsync, RouteRank.Last, autoSignInHandlers: ["me"]);Include code to get access token in message handler using GetTurnTokenAsync method.
var accessToken = await UserAuthorization.GetTurnTokenAsync(turnContext, "me", cancellationToken: cancellationToken);Expected behavior
SSO should work consistently and reliably, maintaining authenticated sessions without unexpected failures.
Screenshots
Microsoft.Hosting.Lifetime: Information: Now listening on: http://localhost:5130
Microsoft.Hosting.Lifetime: Information: Application started. Press Ctrl+C to shut down.
Microsoft.Hosting.Lifetime: Information: Hosting environment: Development
Microsoft.Hosting.Lifetime: Information: Content root path: C:\cea-template-test\MyAgent
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Collections.Immutable.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Net.WebSockets.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Threading.Tasks.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\System.IdentityModel.Tokens.Jwt.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Xml.ReaderWriter.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.IdentityModel.JsonWebTokens.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.IdentityModel.Protocols.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.IdentityModel.Logging.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.IdentityModel.Validators.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Text.RegularExpressions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.IdentityModel.Abstractions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Net.NameResolution.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Formats.Asn1.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Azure.Storage.Common.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Azure.Identity.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.Agents.Storage.Blobs.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Azure.Storage.Blobs.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Diagnostics.TraceSource.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Diagnostics.Tools.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\9.0.9\Microsoft.AspNetCore.WebUtilities.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\OpenTelemetry.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\9.0.9\Microsoft.AspNetCore.Server.HttpSys.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.IO.Compression.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Drawing.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\9.0.9\System.Security.Cryptography.Xml.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\9.0.9\Microsoft.AspNetCore.Html.Abstractions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\9.0.9\Microsoft.AspNetCore.Razor.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\9.0.9\Microsoft.AspNetCore.Razor.Runtime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.Identity.Client.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Net.HttpListener.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\System.IO.Hashing.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Diagnostics.Process.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.Identity.Client.Extensions.Msal.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Security.Cryptography.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Web.HttpUtility.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Security.Cryptography.Algorithms.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\runtimes\win\lib\net8.0\System.Runtime.Caching.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\System.Configuration.ConfigurationManager.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Net.WebClient.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.ComponentModel.EventBasedAsync.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.IdentityModel.LoggingExtensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\cea-template-test\MyAgent\bin\Debug\net9.0\Microsoft.Identity.Web.Certificateless.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
System.Net.Http.HttpClient.MSALClientFactory.LogicalHandler: Information: Start processing HTTP request GET https://login.microsoftonline.com/common/discovery/instance?*
System.Net.Http.HttpClient.MSALClientFactory.ClientHandler: Information: Sending HTTP request GET https://login.microsoftonline.com/common/discovery/instance?*
System.Net.Http.HttpClient.MSALClientFactory.ClientHandler: Information: Received HTTP response headers after 182.37ms - 200
System.Net.Http.HttpClient.MSALClientFactory.LogicalHandler: Information: End processing HTTP request after 199.7567ms - 200
System.Net.Http.HttpClient.MSALClientFactory.LogicalHandler: Information: Start processing HTTP request POST https://login.microsoftonline.com/bf805346-44e7-43f7-8e60-c5e24aefe49c/oauth2/v2.0/token
System.Net.Http.HttpClient.MSALClientFactory.ClientHandler: Information: Sending HTTP request POST https://login.microsoftonline.com/bf805346-44e7-43f7-8e60-c5e24aefe49c/oauth2/v2.0/token
System.Net.Http.HttpClient.MSALClientFactory.ClientHandler: Information: Received HTTP response headers after 120.268ms - 200
System.Net.Http.HttpClient.MSALClientFactory.LogicalHandler: Information: End processing HTTP request after 128.4961ms - 200
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: Start processing HTTP request GET https://api.botframework.com/api/usertoken/GetTokenOrSignInResource?*
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Sending HTTP request GET https://api.botframework.com/api/usertoken/GetTokenOrSignInResource?*
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Received HTTP response headers after 593.9652ms - 200
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: End processing HTTP request after 601.3653ms - 200
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: Start processing HTTP request POST https://smba.trafficmanager.net/emea/bf805346-44e7-43f7-8e60-c5e24aefe49c/v3/conversations/19:gj95SrTsLKCRRw0zeHq1KDbKdCrskF08Rd4J5eET5Vc1@thread.v2/activities/1760431787616
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Sending HTTP request POST https://smba.trafficmanager.net/emea/bf805346-44e7-43f7-8e60-c5e24aefe49c/v3/conversations/19:gj95SrTsLKCRRw0zeHq1KDbKdCrskF08Rd4J5eET5Vc1@thread.v2/activities/1760431787616
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Received HTTP response headers after 881.0739ms - 202
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: End processing HTTP request after 889.5188ms - 202
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Threading.Channels.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: Start processing HTTP request POST https://api.botframework.com/api/usertoken/exchange?*
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Sending HTTP request POST https://api.botframework.com/api/usertoken/exchange?*
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Received HTTP response headers after 483.8107ms - 200
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: End processing HTTP request after 491.7416ms - 200
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: Start processing HTTP request POST https://smba.trafficmanager.net/emea/bf805346-44e7-43f7-8e60-c5e24aefe49c/v3/conversations/19:gj95SrTsLKCRRw0zeHq1KDbKdCrskF08Rd4J5eET5Vc1@thread.v2/activities/1760432019527
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Sending HTTP request POST https://smba.trafficmanager.net/emea/bf805346-44e7-43f7-8e60-c5e24aefe49c/v3/conversations/19:gj95SrTsLKCRRw0zeHq1KDbKdCrskF08Rd4J5eET5Vc1@thread.v2/activities/1760432019527
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Received HTTP response headers after 467.9041ms - 201
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: End processing HTTP request after 475.4054ms - 201
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'MyAgent.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.9\System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
SignUserInAsync exception: Microsoft.Agents.Builder.UserAuth.AuthException: Retry max
at Microsoft.Agents.Builder.UserAuth.TokenService.AgentUserAuthorization.OnContinueFlow(ITurnContext turnContext, FlowState state, CancellationToken cancellationToken)
at Microsoft.Agents.Builder.UserAuth.TokenService.AgentUserAuthorization.OnFlowTurn(ITurnContext turnContext, CancellationToken cancellationToken)
at Microsoft.Agents.Builder.UserAuth.TokenService.AzureBotUserAuthorization.SignInUserAsync(ITurnContext turnContext, Boolean forceSignIn, String exchangeConnection, IList`1 exchangeScopes, CancellationToken cancellationToken)
at Microsoft.Agents.Builder.UserAuth.UserAuthorizationDispatcher.SignUserInAsync(ITurnContext turnContext, String handlerName, Boolean forceSignIn, String exchangeConnection, IList`1 exchangeScopes, CancellationToken cancellationToken)
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: Start processing HTTP request POST https://smba.trafficmanager.net/emea/bf805346-44e7-43f7-8e60-c5e24aefe49c/v3/conversations/19:gj95SrTsLKCRRw0zeHq1KDbKdCrskF08Rd4J5eET5Vc1@thread.v2/activities/1760432124744
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Sending HTTP request POST https://smba.trafficmanager.net/emea/bf805346-44e7-43f7-8e60-c5e24aefe49c/v3/conversations/19:gj95SrTsLKCRRw0zeHq1KDbKdCrskF08Rd4J5eET5Vc1@thread.v2/activities/1760432124744
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.ClientHandler: Information: Received HTTP response headers after 387.9273ms - 201
System.Net.Http.HttpClient.Microsoft.Agents.Builder.RestChannelServiceClientFactory.LogicalHandler: Information: End processing HTTP request after 394.8473ms - 201
At this point we can call our -reset method successfully otherwise it would attempt to continue the auth flow. After the last error, the auth flow seems to be closed correctly and as this method does not use a sign in handler we don't need to enter the auth flow again to remove the token from the token service cache and sign out the user. Sending the next message will result in the same behaviour shown above.
OnMessage("-reset", OnResetAsync, RouteRank.Unspecified);
protected async Task OnResetAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
await UserAuthorization.SignOutUserAsync(turnContext, turnState, "me", cancellationToken: cancellationToken);
turnState.Conversation.ClearConversationHistory();
turnState.Conversation.ClearCachedUserProfile();
await turnContext.SendActivityAsync("Reset complete", cancellationToken: cancellationToken);
}Hosting Information (please complete the following information):
- How are you Hosting this: Local (VS), also an issue in Azure
- Are you deploying: No, but also an issue in
- Are you using Azure Bot Services: Yes
- What Client are you using: M365 Copilot (Teams and Web)
- What .net version is your build in: 9.0
Additional context
This bug appears specific to BlobStorage; other storage providers do not exhibit the same unreliable SSO behaviour. For example, if I replace BlobStorage with MemoryStorage, the issue goes away. I can get a token, reset and get another token with no issues.
Note: I've not tested Azure Cosmos DB, for my scenario this would add additional complexity/cost and would be overkill.