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
有人可以帮我解决这个问题吗?任何帮助,将不胜感激。谢谢
使用 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"]
默认情况下,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"));
我今天也遇到同样的问题,终于解决了。您可以使用以下文件作为示例。
实际上,为我解决这个问题的是添加以下内容:
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"]
我希望它能达到它的目的。
尝试评论这一行:
if (app.Environment.IsDevelopment())
在 Program.cs 文件中在生产环境中启用 swagger