我在.NET8中使用FastEndpoint,并使用FusionAuth实现一个OAuth流.集成运行良好,但我在使用AuthorizationCode Flow时遇到了Swagger用户界面的问题.

我的问题与Swagger UI的oauth2RedirectUrl参数有关.

以下是我设置Swagger并配置其UI的My Program.cs的一个片段:


bld.Services.AddFastEndpoints().AddAuthorization().SwaggerDocument(options =>
{
    //Code...
    // Security scheme used on swagger:
    var securityScheme = new NSwag.OpenApiSecurityScheme
    {
        Type = NSwag.OpenApiSecuritySchemeType.OAuth2,
        Flows = new NSwag.OpenApiOAuthFlows
        {
            AuthorizationCode = new NSwag.OpenApiOAuthFlow
            {
                AuthorizationUrl = authorizationUrl,
                TokenUrl = tokenUrl,
                Scopes = new Dictionary<string, string>
                    {
                        { "offline_access", "Offline access" },
                    }
            }
        },
    };

    options.DocumentSettings = s =>
    {
        //Code...
        //Set security Scheme:
        s.AddAuth("oauth2", securityScheme);
    };
});


app.UseFastEndpoints(o =>
{
  // Code...
}).UseSwaggerGen(o => { }, uiConfig =>
{
    uiConfig.ServerUrl = fusionAuthConfig["RedirectUri"];
    uiConfig.OAuth2Client = new OAuth2ClientSettings
    {
        Realm = "",
        ClientId = fusionAuthConfig["ApplicationId"],
        ClientSecret = fusionAuthConfig["ClientSecret"],
        AppName = fusionAuthConfig["ApplicationId"],
        ScopeSeparator = ",",
        AdditionalQueryStringParameters =
                {
                    { "tenantId", fusionAuthConfig["TenantId"] },
                    { "code_challenge", "XXXXXX" },
                    { "code_challenge_method", "S256" },
                }
    };
});

虚张声势的UI以生成他们具有的UI( SwaggerUiSettings : SwaggerUiSettingsBase):


    internal override async Task<string> TransformHtmlAsync(string html, HttpRequest request, CancellationToken cancellationToken)
    {
        StringBuilder htmlBuilder = new StringBuilder(html);
        OAuth2ClientSettings oAuth2ClientSettings = OAuth2Client ?? new OAuth2ClientSettings();
        foreach (PropertyInfo runtimeProperty in oAuth2ClientSettings.GetType().GetRuntimeProperties())
        {
            object value = runtimeProperty.GetValue(oAuth2ClientSettings);
            if (value is ICollection value2)
            {
                htmlBuilder.Replace("{" + runtimeProperty.Name + "}", JsonConvert.SerializeObject(value2));
            }
            else if (value is bool flag)
            {
                htmlBuilder.Replace("{" + runtimeProperty.Name + "}", flag.ToString().ToLowerInvariant());
            }
            else
            {
                htmlBuilder.Replace("{" + runtimeProperty.Name + "}", value?.ToString() ?? "");
            }
        }

        ICollection<SwaggerUi3Route> collection = ((SwaggerRoutesFactory == null) ? SwaggerRoutes : (await SwaggerRoutesFactory(request, cancellationToken)).ToList());
        ICollection<SwaggerUi3Route> source = collection;
        htmlBuilder.Replace("{Urls}", (!source.Any()) ? "undefined" : JsonConvert.SerializeObject(source.Select((SwaggerUi3Route r) => new SwaggerUi3Route(r.Name, base.TransformToExternalPath(r.Url.Substring(base.MiddlewareBasePath?.Length ?? 0), request)))));
        htmlBuilder.Replace("{ValidatorUrl}", ValidateSpecification ? "undefined" : "null").Replace("{AdditionalSettings}", GenerateAdditionalSettings(AdditionalSettings)).Replace("{EnableTryItOut}", EnableTryItOut.ToString().ToLower())
            .Replace("{RedirectUrl}", string.IsNullOrEmpty(ServerUrl) ? ("window.location.origin + \"" + base.TransformToExternalPath(base.Path, request) + "/oauth2-redirect.html\"") : ("\"" + ServerUrl + base.TransformToExternalPath(base.Path, request) + "/oauth2-redirect.html\""))
            .Replace("{CustomStyle}", GetCustomStyleHtml(request))
            .Replace("{CustomScript}", GetCustomScriptHtml(request))
            .Replace("{CustomHeadContent}", CustomHeadContent)
            .Replace("{DocumentTitle}", DocumentTitle);
        return htmlBuilder.ToString();
    }

他们这样做:

.Replace("{RedirectUrl}", string.IsNullOrEmpty(ServerUrl) ? ("window.location.origin + \"" + base.TransformToExternalPath(base.Path, request) + "/oauth2-redirect.html\"") : ("\"" + ServerUrl + base.TransformToExternalPath(base.Path, request) + "/oauth2-redirect.html\""))

将redirect_url设置为"/oauth2-redirect.html\"

我试着自己设置发送参数的重定向URI,但我想不出方法.我已经试着用AdditionalQueryStringParameters = { "redirect_uri", fusionAuthConfig["RedirectUri"] }发送了 但是我得到了2重定向URI的参数.我知道在Swagger中有一个名为oauth2RedirectUrl(https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/)的参数,但我无法更改它.

有谁知道我怎样才能改变这个参数?

谢谢.

推荐答案

在达到FE staff community on Discord人后,我们很快就开始工作了.

只需使用:uiConfig.AdditionalSettings["oauth2RedirectUrl"] = fusionAuthConfig["RedirectUriSwagger"];设置参数即可

因此,我们有:

.UseSwaggerGen(o => { }, uiConfig =>
{
    uiConfig.AdditionalSettings["oauth2RedirectUrl"] = fusionAuthConfig["RedirectUriSwagger"];
    uiConfig.ServerUrl = fusionAuthConfig["RedirectUri"];
    uiConfig.OAuth2Client = new OAuth2ClientSettings
    {
        ClientId = fusionAuthConfig["ApplicationId"],
        ClientSecret = fusionAuthConfig["ClientSecret"],
        AppName = fusionAuthConfig["ApplicationId"],
        ScopeSeparator = ",",
        AdditionalQueryStringParameters =
                {
                    { "tenantId", fusionAuthConfig["TenantId"] },
                    { "code_challenge", "CCCCCCC" },
                    { "code_challenge_method", "S256" },
                }
    };
});

Csharp相关问答推荐

.NET最小API映射将T参数列表为[FromQuery]

. NET Core DB vs JSON模型设计

如何注册接口类型,类型<>

为什么SignalR在每个Blazor服务器应用程序启动时最多启动8个服务器?

Blazor服务器端的身份验证角色

如何使datagridview的列具有响应性,以便不是所有列都更改其宽度

使用两个不同的枚举作为Switch语句中的CASE生成唯一值

在Docker容器中运行API项目时,无法本地浏览到index.html

按需无缝转码单个HLS数据段

等待一个等待函数

如何让两个.NET版本不兼容的项目对话?

在C#中,是否有与变量DISARD对应的C++类似功能?

如何在GRPC代码First服务的返回类型上使用多态性?

如何在Polly重试策略成功之前将HttpClient请求排队?

用MongoDB c#驱动程序删除和返回嵌套数组中的文档

使用免费的DotNet库从Azure函数向Azure文件共享上的现有Excel文件追加行

LINQ在GROUP BY和JOIN之后获取子列表

如何模拟一个返回OneOf IServiceA,IServiceB的方法?使用Moq

组件';EditForm';使用与包含子内容元素';授权';相同的参数名称(';上下文';)

C#AWS S3上载损坏的文件