11using Microsoft . Extensions . Logging ;
22using Microsoft . Extensions . Logging . Abstractions ;
3+ using System . Collections . Specialized ;
34using System . Diagnostics . CodeAnalysis ;
45using System . Security . Cryptography ;
56using System . Text ;
@@ -127,8 +128,6 @@ public ClientOAuthProvider(
127128 {
128129 ThrowIfNotBearerScheme ( scheme ) ;
129130
130- // REVIEW: Should we be doing anything with the resourceUri? If not, why is it part of the IMcpCredentialProvider interface?
131-
132131 // Return the token if it's valid
133132 if ( _token != null && _token . ExpiresAt > DateTimeOffset . UtcNow . AddMinutes ( 5 ) )
134133 {
@@ -138,7 +137,7 @@ public ClientOAuthProvider(
138137 // Try to refresh the token if we have a refresh token
139138 if ( _token ? . RefreshToken != null && _authServerMetadata != null )
140139 {
141- var newToken = await RefreshTokenAsync ( _token . RefreshToken , _authServerMetadata , cancellationToken ) . ConfigureAwait ( false ) ;
140+ var newToken = await RefreshTokenAsync ( _token . RefreshToken , resourceUri , _authServerMetadata , cancellationToken ) . ConfigureAwait ( false ) ;
142141 if ( newToken != null )
143142 {
144143 _token = newToken ;
@@ -276,15 +275,15 @@ private async Task PerformOAuthAuthorizationAsync(
276275 return null ;
277276 }
278277
279- private async Task < TokenContainer > RefreshTokenAsync ( string refreshToken , AuthorizationServerMetadata authServerMetadata , CancellationToken cancellationToken )
278+ private async Task < TokenContainer > RefreshTokenAsync ( string refreshToken , Uri resourceUri , AuthorizationServerMetadata authServerMetadata , CancellationToken cancellationToken )
280279 {
281280 var requestContent = new FormUrlEncodedContent ( new Dictionary < string , string >
282281 {
283282 [ "grant_type" ] = "refresh_token" ,
284283 [ "refresh_token" ] = refreshToken ,
285284 [ "client_id" ] = GetClientIdOrThrow ( ) ,
286285 [ "client_secret" ] = _clientSecret ?? string . Empty ,
287- // Add resource
286+ [ "resource" ] = resourceUri . ToString ( ) ,
288287 } ) ;
289288
290289 using var request = new HttpRequestMessage ( HttpMethod . Post , authServerMetadata . TokenEndpoint )
@@ -311,7 +310,7 @@ private async Task<TokenContainer> RefreshTokenAsync(string refreshToken, Author
311310 return null ;
312311 }
313312
314- return await ExchangeCodeForTokenAsync ( authServerMetadata , authCode ! , codeVerifier , cancellationToken ) . ConfigureAwait ( false ) ;
313+ return await ExchangeCodeForTokenAsync ( protectedResourceMetadata , authServerMetadata , authCode ! , codeVerifier , cancellationToken ) . ConfigureAwait ( false ) ;
315314 }
316315
317316 private Uri BuildAuthorizationUrl (
@@ -326,7 +325,7 @@ private Uri BuildAuthorizationUrl(
326325 }
327326
328327 var queryParams = HttpUtility . ParseQueryString ( string . Empty ) ;
329- queryParams [ "client_id" ] = _clientId ;
328+ queryParams [ "client_id" ] = GetClientIdOrThrow ( ) ;
330329 queryParams [ "redirect_uri" ] = _redirectUri . ToString ( ) ;
331330 queryParams [ "response_type" ] = "code" ;
332331 queryParams [ "code_challenge" ] = codeChallenge ;
@@ -348,6 +347,7 @@ private Uri BuildAuthorizationUrl(
348347 }
349348
350349 private async Task < TokenContainer > ExchangeCodeForTokenAsync (
350+ ProtectedResourceMetadata protectedResourceMetadata ,
351351 AuthorizationServerMetadata authServerMetadata ,
352352 string authorizationCode ,
353353 string codeVerifier ,
@@ -361,7 +361,7 @@ private async Task<TokenContainer> ExchangeCodeForTokenAsync(
361361 [ "client_id" ] = GetClientIdOrThrow ( ) ,
362362 [ "code_verifier" ] = codeVerifier ,
363363 [ "client_secret" ] = _clientSecret ?? string . Empty ,
364- // TODO: Add resource
364+ [ "resource" ] = protectedResourceMetadata . Resource . ToString ( ) ,
365365 } ) ;
366366
367367 using var request = new HttpRequestMessage ( HttpMethod . Post , authServerMetadata . TokenEndpoint )
0 commit comments