@@ -605,6 +605,17 @@ async function discoverMetadataWithFallback(
605
605
return response ;
606
606
}
607
607
608
+ /**
609
+ * Identify common providers from metadata
610
+ * Used for providers that have quirks needing conditional handling
611
+ * e.g. Azure no PKCE advertised, scope param instead of resource param.
612
+ */
613
+ function identifyProvider ( metadata : AuthorizationServerMetadata ) : "azure_v2" | undefined {
614
+ if ( metadata . issuer . includes ( "login.microsoftonline.com" ) ) {
615
+ return "azure_v2"
616
+ }
617
+ }
618
+
608
619
/**
609
620
* Looks up RFC 8414 OAuth 2.0 Authorization Server Metadata.
610
621
*
@@ -778,6 +789,10 @@ export async function discoverAuthorizationServerMetadata(
778
789
return OAuthMetadataSchema . parse ( await response . json ( ) ) ;
779
790
} else {
780
791
const metadata = OpenIdProviderDiscoveryMetadataSchema . parse ( await response . json ( ) ) ;
792
+ // Azure Bypass
793
+ if ( identifyProvider ( metadata ) === "azure_v2" && ! metadata . code_challenge_methods_supported ) {
794
+ metadata . code_challenge_methods_supported = [ "S256" ] ;
795
+ }
781
796
782
797
// MCP spec requires OIDC providers to support S256 PKCE
783
798
if ( ! metadata . code_challenge_methods_supported ?. includes ( 'S256' ) ) {
@@ -869,7 +884,11 @@ export async function startAuthorization(
869
884
}
870
885
871
886
if ( resource ) {
872
- authorizationUrl . searchParams . set ( "resource" , resource . href ) ;
887
+ if ( metadata && identifyProvider ( metadata ) === "azure_v2" ) {
888
+ authorizationUrl . searchParams . set ( "scope" , `${ resource . href } /.default` ) ;
889
+ } else {
890
+ authorizationUrl . searchParams . set ( "resource" , resource . href ) ;
891
+ }
873
892
}
874
893
875
894
return { authorizationUrl, codeVerifier } ;
@@ -947,7 +966,11 @@ export async function exchangeAuthorization(
947
966
}
948
967
949
968
if ( resource ) {
950
- params . set ( "resource" , resource . href ) ;
969
+ if ( metadata && identifyProvider ( metadata ) === "azure_v2" ) {
970
+ params . set ( "scope" , `${ resource . href } /.default` ) ;
971
+ } else {
972
+ params . set ( "resource" , resource . href ) ;
973
+ }
951
974
}
952
975
953
976
const response = await ( fetchFn ?? fetch ) ( tokenUrl , {
@@ -1031,7 +1054,11 @@ export async function refreshAuthorization(
1031
1054
}
1032
1055
1033
1056
if ( resource ) {
1034
- params . set ( "resource" , resource . href ) ;
1057
+ if ( metadata && identifyProvider ( metadata ) === "azure_v2" ) {
1058
+ params . set ( "scope" , `${ resource . href } /.default` ) ;
1059
+ } else {
1060
+ params . set ( "resource" , resource . href ) ;
1061
+ }
1035
1062
}
1036
1063
1037
1064
const response = await ( fetchFn ?? fetch ) ( tokenUrl , {
0 commit comments