Skip to content

Commit 5b20710

Browse files
committed
Add RFC 8707 to the client and TestOAuthServer
1 parent a3e8601 commit 5b20710

4 files changed

Lines changed: 15 additions & 3 deletions

File tree

src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ private Uri BuildAuthorizationUrl(
295295
queryParams["response_type"] = "code";
296296
queryParams["code_challenge"] = codeChallenge;
297297
queryParams["code_challenge_method"] = "S256";
298+
queryParams["resource"] = protectedResourceMetadata.Resource.ToString();
298299

299300
var scopesSupported = protectedResourceMetadata.ScopesSupported;
300301
if (_scopes is not null || scopesSupported.Count > 0)

tests/ModelContextProtocol.AspNetCore.Tests/AuthTests.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public class AuthTests : KestrelInMemoryTest, IAsyncDisposable
1616
{
1717
private const string McpServerUrl = "http://localhost:5000";
1818
private const string OAuthServerUrl = "https://localhost:7029";
19-
private const string ClientId = "demo-client";
2019

2120
private readonly CancellationTokenSource _testCts = new();
2221
private readonly Task _oAuthRunTask;
@@ -45,7 +44,7 @@ public AuthTests(ITestOutputHelper outputHelper)
4544
ValidateAudience = true,
4645
ValidateLifetime = true,
4746
ValidateIssuerSigningKey = true,
48-
ValidAudience = ClientId,
47+
ValidAudience = McpServerUrl,
4948
ValidIssuer = OAuthServerUrl,
5049
NameClaimType = "name",
5150
RoleClaimType = "roles"

tests/ModelContextProtocol.TestOAuthServer/ClientInfo.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ internal sealed class ClientInfo
2121
/// Gets or sets the list of redirect URIs allowed for this client.
2222
/// </summary>
2323
public List<string> RedirectUris { get; init; } = [];
24+
25+
/// <summary>
26+
/// Gets or sets the list of valid resources for this client.
27+
/// </summary>
28+
public List<string> ValidResources { get; init; } = [];
2429
}

tests/ModelContextProtocol.TestOAuthServer/Program.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ public async Task RunServerAsync(string[]? args = null, CancellationToken cancel
9898
{
9999
ClientId = clientId,
100100
ClientSecret = clientSecret,
101-
RedirectUris = ["http://localhost:1179/callback"]
101+
RedirectUris = ["http://localhost:1179/callback"],
102+
ValidResources = ["http://localhost:5000/"],
102103
};
103104

104105
// OIDC and OAuth Metadata
@@ -209,6 +210,12 @@ public async Task RunServerAsync(string[]? args = null, CancellationToken cancel
209210
return Results.Redirect($"{redirect_uri}?error=invalid_request&error_description=Only+S256+code_challenge_method+is+supported&state={state}");
210211
}
211212

213+
// Validate resource in accordance with RFC 8707
214+
if (string.IsNullOrEmpty(resource) || !client.ValidResources.Contains(resource))
215+
{
216+
return Results.Redirect($"{redirect_uri}?error=invalid_target&error_description=The+specified+resource+is+not+valid&state={state}");
217+
}
218+
212219
// Generate a new authorization code
213220
var code = OAuthUtils.GenerateRandomToken();
214221
var requestedScopes = scope?.Split(' ').ToList() ?? new List<string>();

0 commit comments

Comments
 (0)