@@ -345,6 +345,23 @@ string NormalizeCallbackHost(HttpContext ctx)
345345 $ "&response_mode=query" +
346346 $ "&prompt={ promptType } ";
347347
348+ // For prompt=none silent flows, add login_hint to disambiguate the user
349+ // (otherwise AADSTS16000 interaction_required when multiple identities exist).
350+ if ( promptType == "none" )
351+ {
352+ var azureUserJson = ctx . Session . GetString ( "azure_user" ) ;
353+ if ( ! string . IsNullOrEmpty ( azureUserJson ) )
354+ {
355+ try
356+ {
357+ var u = JsonSerializer . Deserialize < JsonElement > ( azureUserJson ) ;
358+ if ( u . TryGetProperty ( "email" , out var emailProp ) && emailProp . ValueKind == JsonValueKind . String )
359+ url += $ "&login_hint={ Uri . EscapeDataString ( emailProp . GetString ( ) ! ) } ";
360+ }
361+ catch { }
362+ }
363+ }
364+
348365 logger . LogInformation ( "Microsoft OAuth redirect: tier={Tier} prompt={Prompt} tenant={Tenant} from {Host}" , tier , promptType , effectiveTenant , ctx . Request . Host ) ;
349366 return Results . Redirect ( url ) ;
350367} ) ;
@@ -409,6 +426,11 @@ string NormalizeCallbackHost(HttpContext ctx)
409426
410427 var grantedTenant = ctx . Request . Query [ "tenant" ] . ToString ( ) ;
411428 logger . LogInformation ( "Admin consent granted for tenant={Tenant}" , grantedTenant ) ;
429+ // Pin auth_tenant to the just-consented tenant so the silent chain that
430+ // follows uses the correct tenant authority (prompt=none on /common will
431+ // fail with AADSTS16000 interaction_required).
432+ if ( ! string . IsNullOrEmpty ( grantedTenant ) )
433+ ctx . Session . SetString ( "auth_tenant" , grantedTenant ) ;
412434 return Results . Redirect ( "/?admin_consent=ok&tenant=" + Uri . EscapeDataString ( grantedTenant ) ) ;
413435} ) ;
414436
0 commit comments