using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using Microsoft.Net.Http.Headers; using Volo.Abp.DependencyInjection; namespace Sozsoft.Mcp; /// /// /mcp'den donen 401 yanitina korumali kaynak meta verisinin adresini ekler (RFC 9728 §5.1). /// Uzak MCP istemcisi OAuth akisini bu basliktan baslatir; baslik yoksa baglanti formu /// "kimlik dogrulama desteklenmiyor" diye durur. Kimlik dogrulamadan once calismalidir: /// basligi yanit baslamadan hemen once yazar, 401'i hangi katman uretmis olursa olsun. /// public class McpAuthenticationChallengeMiddleware(IOptions options) : IMiddleware, ITransientDependency { public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (context.Request.Path.StartsWithSegments(McpConsts.EndpointPath)) { context.Response.OnStarting(() => { if (context.Response.StatusCode == StatusCodes.Status401Unauthorized) { context.Response.Headers[HeaderNames.WWWAuthenticate] = $"Bearer resource_metadata=\"{options.Value.ProtectedResourceMetadataUrl}\", " + $"scope=\"{string.Join(' ', McpConsts.OAuthScopes)}\""; } return Task.CompletedTask; }); } await next(context); } }