Swagger 无法在 .Net core 项目的 Docker 中工作?

问题描述 投票:0回答:4

net core Web API 应用程序。我已经使用 Azure AD 身份验证创建了 swagger。当我使用 IIS 时,我的 swagger 可以正常工作。当我使用 docker 运行时,我得到此站点无法访问。下面是我的启动代码。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        azureActiveDirectoryOptions = configuration.GetSection("AzureAd").Get<AzureActiveDirectoryOptions>();
        swaggerUIOptions = configuration.GetSection("Swagger").Get<SwaggerUIOptions>();
    }

    public IConfiguration Configuration { get; }

    private readonly AzureActiveDirectoryOptions azureActiveDirectoryOptions;
    private readonly SwaggerUIOptions swaggerUIOptions;
    //
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services
           .AddAuthentication(o =>
           {
               o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;

           })
           .AddJwtBearer(o =>
           {
               o.Authority = azureActiveDirectoryOptions.Authority;

               o.TokenValidationParameters = new TokenValidationParameters
               {

                   ValidAudiences = new List<string>
                   {
                      azureActiveDirectoryOptions.AppIdUri,
                      azureActiveDirectoryOptions.ClientId
                   },
                   ValidateIssuer = true,
                   ValidateAudience = true,
                   ValidIssuer = "https://KmartAus.onmicrosoft.com/oauth2/default",
                   RoleClaimType = ClaimTypes.Role
               };
           });

        services.AddMvc(options =>
        {

            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); ;

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });

            c.AddSecurityDefinition("oauth2", new OAuth2Scheme
            {
                Type = "oauth2",
                Flow = "implicit",
                AuthorizationUrl = swaggerUIOptions.AuthorizationUrl,
                TokenUrl = swaggerUIOptions.TokenUrl,
                Scopes = new Dictionary<string, string>
                {
                    {"Read", "13269k8-a2ea-45a1-96e7-6580f57b6e30/.default" }
                }
            });
            c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
            {
                    { "oauth2", new[] { "readAccess", "writeAccess" } }
            });
        });


    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {

            c.OAuthClientId(swaggerUIOptions.ClientId);
            c.OAuthClientSecret(swaggerUIOptions.ClientSecret);
            c.OAuthRealm(azureActiveDirectoryOptions.ClientId);
            c.OAuthAppName("Swagger");
            //c.OAuthAdditionalQueryStringParams(new { resource = azureActiveDirectoryOptions.ClientId });
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
        app.UseAuthentication();
        app.UseMvc();
    }
}

下面是我的 docker 文件。

FROM microsoft/dotnet:2.1-sdk AS build
ENV ASPNETCORE_URLS http://*:44319
EXPOSE 44319
WORKDIR /src
COPY ["LocationServicesAPI/LocationServicesAPI.csproj", "LocationServicesAPI/"]
RUN dotnet restore "LocationServicesAPI/LocationServicesAPI.csproj"

COPY . .
WORKDIR /src/LocationServicesAPI/


RUN dotnet build LocationServicesAPI.csproj -c Release -o /app

ENTRYPOINT ["dotnet", "LocationServicesAPI.dll"]

当我在 Docker 上运行时,http://localhost:54330/ 在浏览器中启动,如果我点击 http://localhost:54330/swagger/index.html 则不会打开任何内容。如果我尝试点击 http://localhost:44319/swagger/index.html 那么我也无法打开 swagger。下面是我执行 docker ps 时的容器端口映射。

44319/tcp,0.0.0.0:54330->80/tcp 容器内存在以下文件。

Controllers  Dockerfile  LocationServicesAPI.csproj  LocationServicesAPI.csproj.user  Models  Program.cs  Properties  Startup.cs  appsettings.Development.json  appsettings.json  bin  obj  out  wwwroot

有人可以帮我解决这个问题吗?任何帮助,将不胜感激。谢谢

c# docker asp.net-core .net-core swagger
4个回答
25
投票

使用 ASP.NET Core 的默认配置,swagger 仅适用于开发环境。将以下环境变量添加到您的 Dockerfile

FROM microsoft/dotnet:2.1-sdk AS build
ENV ASPNETCORE_URLS http://*:44319

ENV ASPNETCORE_ENVIRONMENT=Development #Add this line.

EXPOSE 44319
WORKDIR /src
COPY ["LocationServicesAPI/LocationServicesAPI.csproj", "LocationServicesAPI/"]
RUN dotnet restore "LocationServicesAPI/LocationServicesAPI.csproj"

COPY . .
WORKDIR /src/LocationServicesAPI/


RUN dotnet build LocationServicesAPI.csproj -c Release -o /app

ENTRYPOINT ["dotnet", "LocationServicesAPI.dll"]


6
投票

默认情况下,swagger UI 只能在 dev env 中访问,因此您可以将 env 更改为 dev,或者更改应用程序中间件中的条件,以便将 swagger 中间件排除在该条件之外

 if (env.IsDevelopment())
   {
     app.UseDeveloperExceptionPage();
     app.UseSwagger();
     app.UseSwaggerUI(c => 
     c.SwaggerEndpoint("/swagger/v1/swagger.json", "myappname v1"));
    }

所以就会变成这样

if (env.IsDevelopment()) {...}
   app.UseSwagger();
   app.UseSwaggerUI(c => 
   c.SwaggerEndpoint("/swagger/v1/swagger.json","myappname v1")); 

0
投票

我今天也遇到同样的问题,终于解决了。您可以使用以下文件作为示例。

实际上,为我解决这个问题的是添加以下内容:

ENV ASPNETCORE_ENVIRONMENT=Development

这是整个 dockerfile :

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /app

COPY ./*.csproj ./ RUN dotnet restore

COPY . .

RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime WORKDIR /app COPY
--from=build /app/out ./

ENV ASPNETCORE_ENVIRONMENT=Development

EXPOSE 80 

ENTRYPOINT ["dotnet", "ProjectName.dll"]

我希望它能达到它的目的。


0
投票

尝试评论这一行:

if (app.Environment.IsDevelopment())

在 Program.cs 文件中在生产环境中启用 swagger

© www.soinside.com 2019 - 2024. All rights reserved.