How to use Azure AD with OpenId Connect in a iFrame - iframe

I've just been looking for hours for a way to call a web app in an iFrame that is protected with OpenId Connect SSO.
Current status is that either the following message appears with the link https://localhost:5001/signin-oidc.
Or the following error message with the link https://localhost:5001 :
If the application is called directly via the browser, then the login screen of Azure appears as desired. Only when I go via the iFrame, nothing works anymore. Even if I open the application first and log in, it does not work with iFrame.
The settings were made with the default template of Rider
csproj
...
<UserSecretsId>SomeGuideWithName</UserSecretsId>
<WebProject_DirectoryAccessLevelKey>0</WebProject_DirectoryAccessLevelKey>
...
App.razor
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)"/>
<FocusOnNavigate RouteData="#routeData" Selector="h1"/>
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="#typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
appsettings.json
xxx --> Secreds that are correct.
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxx.onmicrosoft.com",
"TenantId": "xxx",
"ClientId": "xxx",
"CallbackPath": "/signin-oidc"
}
Program.cs
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using MitAuth.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
builder.Services.AddAuthorization(
options =>
{
// By default, all incoming requests will be authorized according to the default policy
options.FallbackPolicy = options.DefaultPolicy;
}
);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
builder.Services.AddSingleton<WeatherForecastService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
Generated Cookies
The goal is to have application A (Caller) embed an iFrame that application B (OpenIdConnect protected).
Questions:
Do I need to reconfigure anything in App B?
Do I need to do anything else in App A?
Is there any token or similar that has to be passed on?

I tried to reproduce the scenario in my environment:
I got the same error:
System.Exception: An error was encountered while handling the remote login.
---> System.Exception: OpenIdConnectAuthenticationHandler: message.State is null or empty.
Here due to misconfiguration in callback path I got the error.
In your case check without giving callbackpath in both code and portal.
Appsettings.json:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "mytenantxxx.onmicrosoft.com",
"TenantId": "fbxxxxxxxxxxxxf3b0",
"ClientSecret": "xxxx",
"ClientId": "xxxx",
"CallbackPath": "/"
},
I have configured following redirect urls in portal.
My application url uses http protocol http://localhost:44328
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy
options.FallbackPolicy = options.DefaultPolicy;
});
services.AddRazorPages();
services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
services.AddSingleton<WeatherForecastService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
IdentityModelEventSource.ShowPII = true;
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
When I changed the CallbackPath value to /signin-oidc , that error was resolved.
Appsettings.json:
"AzureAd": {
...
"CallbackPath": "/signin-oidc"
},
Also check Exception: Correlation failed. AAD + Azure Front Door

Related

Blocked by CORS policy despite having policy added to allow any and middleware set

I have been stuck on this issue for days. I'm attempting to add a CORS policy so my application does not require a CORS plugin (extension) to run. I've went through multiple tutorials of how to correctly implement the add policy and how to order the middleware. My application backend should send map data to the front end but without the plugin I receive the infamous
Access to XMLHttpRequest at 'http://localhost:5001/maps/NaturalEarthII/tilemapresource.xml' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. error. From my understanding everything is setup as it should be but the results are not agreeing, Please help! There is no controllers
ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
// Enable Gzip Response Compression for SRTM terrain data
services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/vnd.quantized-mesh" });
options.Providers.Add<GzipCompressionProvider>();
});
// Add CORS Service so Tile Server works
services.AddCors(options =>
{
//Here ive attepted implementing default and specific policy
//I've also tried only allowing specific origins and allowing any method + header
//no luck. I will change this to be more specific once i get maps to show
options.AddDefaultPolicy(
builder => builder.AllowAnyOrigin()
);
options.AddPolicy("allowAny",
builder => builder.WithOrigins("http://localhost:5001")
.SetIsOriginAllowed((host) => true)
.AllowAnyMethod().AllowAnyHeader()
);
});
services.AddControllers();
//services.AddSpaStaticFiles(config => config.RootPath = "wwwroot");
services.AddSingleton(typeof(MessageBus), new MessageBus());
}
Configure method:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Microsoft.Extensions.Hosting.IHostApplicationLifetime applicationLifetime)
{
applicationLifetime.ApplicationStopping.Register(OnShutdown);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Use Gzip Response Compression for SRTM terrain data
app.UseResponseCompression();
// We must set the Content-Type and Content-Encoding for SRTM terrain files,
// so the Client's Web Browser can display them.
app.Map("/terrain/srtm", fileApp =>
{
fileApp.Run(context =>
{
if (context.Request.Path.Value.EndsWith(".terrain")) {
context.Response.Headers["Content-Type"] = "application/vnd.quantized- mesh";
context.Response.Headers["Content-Encoding"] = "gzip";
}
return context.Response.SendFileAsync(
Path.Combine(Directory.GetCurrentDirectory(), ("data/terrain/srtm/" + context.Request.Path.Value)));
});
});
Console.WriteLine(Path.Combine(Directory.GetCurrentDirectory() + "data"));
// Make the data/maps directory available to clients
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "data")),
});
app.UseRouting();
//Add the default policy thats create in the conf services method
app.UseCors();
app.UseAuthorization();
app.UseWebSockets();
app.UseEndpoints(endpoints => endpoints.MapControllers().RequireCors("allowAny"));
bus = (MessageBus)app.ApplicationServices.GetService(typeof(MessageBus));
...
In the Add cors Ive attempted implementing default and specific policy
I've also tried only allowing specific origins and allowing any method + header. No luck. I will change this to be more specific once i get maps to show
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder => builder.AllowAnyOrigin()
);
options.AddPolicy("allowAny",
builder => builder.WithOrigins("http://localhost:5001")
.SetIsOriginAllowed((host) => true)
.AllowAnyMethod().AllowAnyHeader()
);
});
After trying endless attempts at making the back end work I gave up and implemented a reverse proxy on the front end. I can now use my web application without a CORS plugin.
proxy.conf.json:
{
"/maps":{
"target": "http://localhost:5001",
"secure": false
}
}
angular.json:
...
"serve": {
"builder": "#angular-devkit/build- angular:dev-server",
"options": {
"browserTarget": "cesium-angular:build",
"proxyConfig": "src/proxy.conf.json"
},
...
You are setting your allowed origin to be the service itself rather than address of your UI.
In your case your origin should be http://localhost:4200 not 5001
Add this to your program.cs
var app = builder.Build();
...
app.UseCors(policy => policy.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.WithOrigins("https://localhost:4200"));
Do note that the UseCors() needs to be called before UseAuthentication() and UseAuthorization()
I also can't see where you are calling your ConfigureServices method

How to Access ASP.NET Web API Backend with Mobile Phone Android Browser using Angular Local Host

I am building my first website (total newbie) using Angular and ASP.NET Web API. I can access my web app on localhost 4200 and using 192.168.100.2:4200 on my pc browser.
But when I try to log on the same localhost with a Mobile Phone Android Browser, It returns a server error.
Following are the commands I tried
ng serve --host 192.168.100.2
ng serve --host 192.168.100.2 --disable-host-check
ng serve --host 0.0.0.0
This is my Login method on the Component
login(){
if(this.loginForm.valid){
const record = this.loginForm.getRawValue();
console.log(record);
this.authService.login({
username: record.userName,
password: record.password,
}).subscribe({
next:(data: any) => {
this.authService.authToken = JSON.parse(data).token;
console.log("Orig Token: ", data);
console.log("Parsed Token: ", this.authService.authToken);
console.log("Parsed Token (Subject): ", this.authService.authToken.split('.')[1]);
console.log("JSON (after atob) ",this.authService.atob);
console.log("Object (Payload): ",this.authService.payLoad);
console.log("User id: ",this.authService.userID);
console.log("Name: ",this.authService.userName);
console.log("Modules: ",this.authService.accessibleModulesOfUser);
this.router.navigateByUrl('');
this.toastr.success("Welcome Back.")
},
error: (e) => {
if (e.status == 0) {
// this.msgs.push({ severity: 'warn', detail: 'Server is not available. Please try again later.' });
// this.toastr.error("Server is not available. Please try again later")
this.toastr.error("Server is not available. Please try again later")
}
else if (e.status == ApiCallStatusCodes.UNAUTHORIZED) {
// this.msgs.push({ severity: 'error', detail: err.error });
// console.log(e);
this.toastr.error(e.error)
}
else {
// this.msgs.push({ severity: 'warn', detail: err.error });
// console.log(e);
this.toastr.error(e.error)
}
}
})
}
else{
this.toastr.warning("Enter username and password.")
}
}
I already try adding Inbound Rule to my Windows Defender Firewal but it doesnt work.
Also, I modify the CORS in startup of ASP.NET but still has no luck.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPIv5 v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(policy => policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200", "http://192.168.100.2:4200"));
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

Request ignored because of CORS in IdentityServer4

I have 3 projects:
Client App
ASP.NET API App
IdentityServer4 MVC App
I am able to send a request from API to IDP but trying to send a request from Client to IDP yields
"CORS request made for path: /api/Trial/TrialAction from origin: https://localhost:44389 but
was ignored because path was not for an allowed IdentityServer CORS endpoint"
even though I added the following to the IDP:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", policyBuilder => policyBuilder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
and
// ...
app.UseRouting();
app.UseIdentityServer();
app.UseCors("CorsPolicy");
app.UseAuthorization();
// ...
The interesting part is, I can send a request from API to IDP without adding CORS configuration to IDP. What am I doing wrong?
Config.cs:
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{
new ApiResource("myapi",
"My API",
new [] { "membershipType" }
)
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
ClientId = "mywebclient",
ClientName = "My Web Client",
AllowedGrantTypes = GrantTypes.Code, // Authorization code flow with PKCE protection
RequireClientSecret = false, // Without client secret
RequirePkce = true,
RedirectUris = { "https://localhost:44389/authentication/login-callback" },
PostLogoutRedirectUris = { "https://localhost:44389/authentication/logout-callback" },
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"albidersapi"
},
AllowedCorsOrigins = { "https://localhost:44389" },
RequireConsent = false,
}
};
}
do yo have the client and API in the same project as IdentityServer? I typically recommend that you keep them apart.
A wild guess could be to swap these two lines:
app.UseIdentityServer();
app.UseCors("CorsPolicy");
Because apparently IdentityServer captures the request to the API?
The most likely issue is that your call from your client to your API is not including the access token.
The debug log is coming from this file here. If you look at where your debug statement is originating from you will see that it is checking if the path matches any within IdentityServerOptions.Cors.CorsPaths. Here is an image of what those paths generally are from a debug service I made.
These paths are just the default information and authentication endpoints for IdentityServer4. In other words it thinks your request is unauthenticated because it likely isn't including the access token.
If you are using IdentityServer4's template logging implementation with Serilog, then you can also add this to your appsettings.json to see what the ASP.NET Core CORS middleware has to say. It will be logging after IdentityServer4's log
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.AspNetCore.Authentication": "Debug",
"Microsoft.AspNetCore.Cors": "Information",
"System": "Warning"
}
}
}
Here is what my debug log looked like when I made a request to an endpoint with a proper CORS policy, but the request didn't include its access token.
[21:05:47 Debug] IdentityServer.Hosting.CorsPolicyProvider CORS request made for path: /api/v1.0/users/{guid}/organizations from origin: https://localhost:44459 but was ignored because path was not for an allowed IdentityServer CORS endpoint
[21:05:47 Information] Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware No CORS policy found for the specified request.
So it's not a CORS issue really. It's an access token or authentication issue. It is also possible, however, that your endpoint isn't being hit properly. However, you should be receiving a 404 on the client in addition to the log seen above.

Azure AD B2C Web API Using .NET Core 2

I’m trying to call a Web API from a Web App both protected by Azure AD B2C. The App signs in fine with the Azure sign in page. But when I call my [Authorize] endpoint on my API I get a 401 unauthorized response.
I thought this is supposed to work right out of the box using VS2017 and ASP.NET Core 2.1. When I created both apps I specified “Individual User Accounts” for authentication and “Connect to an existing user store in the cloud”. The examples I’ve found seem to be from .NET Core 1 or older and no longer relevant or using deprecated setups.
I have the App in the API access section with read and write scopes in Azure.
How do I successfully authorize my App to call my API?
Here’s my App Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// 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.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
My App appsettings.json:
{
"AzureAdB2C": {
"Instance": "https://myCompanyPassport.b2clogin.com/tfp/",
"ClientId": "51dde0de-a204-4b67-b890-068846e17ff1",
"ClientSecret": "------------------------",
"CallbackPath": "/signin-oidc",
"Domain": "myCompanyPassport.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_myCompanySignUpSignIn",
"ResetPasswordPolicyId": "B2C_1_myCompanyPasswordReset",
"EditProfilePolicyId": "B2C_1_myCompanyProfile",
"TaskServiceUrl": "https://localhost:44337/",
"ApiIdentifier": "https://myCompanyPassport.onmicrosoft.com/taskapi",
"ReadScope": "read",
"WriteScope": "write"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
Here’s my API Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
.AddAzureADB2CBearer(options => Configuration.Bind("AzureAdB2C", options));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// 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.UseHttpsRedirection();
app.UseAuthentication();
app.UseMvc();
}
My API appsettings.json:
{
"AzureAdB2C": {
"Instance": "https://myCompanyPassport.b2clogin.com/tfp/",
"ClientId": "213764b3-8c2a-4bf6-9e69-355495a8f14e",
"ClientSecret": "------------------------",
"Domain": "myCompanyPassport.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_myCompanySignUpSignIn",
"ReadScope": "read",
"WriteScope": "write"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
Did you try this ( addazureadbearer api )
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));

Can't read swagger JSON file on ASP.NET Core 1.2 Application after hosting into local IIS

After hosting my asp.net core 1.2 application, I am getting an error as:
swagger is unable to find the swagger.json file.
I have tried to solve the problem by giving a virtual path name app.UseSwaggerUI() but it's not working.
Edit to clarify question based on comments:
After hosting Asp.net core application in IIS, the swagger.json file is generating on localhost:<random_port>/swagger/v1/swagger.json path.
How do I serve the swagger.json file on a custom route like:
localhost:<random_port>/virtualpathname/swagger/v1/swagger.json
I have tried to set a virtual path in app.UseSwaggerUI() like {virtualpathname}/swagger/v2/swagger.json but still it is not working
Could be a few reasons for this - one being that .Net Core doesnt serve static files by default (although looking at online examples this doesnt seem to be an issue).
If you havent already, try installing the package Microsoft.AspNetCore.StaticFiles and adding UseStaticFiles() in your Configure() method in Startup.cs with the following configuration. I dont think that the order is important, but this is the order I have mine running in a working app.
public void Configure(...)
{
// Enable middleware to serve static files (like .json)
app.UseStaticFiles();
//Enable middleware for your API
app.UseMvc();
// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger();
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "YourApp API V1");
});
}
You will also need SwaggerGen middleware configured in your ConfigureServices() method.
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "api_name", Version = "1.0"});
});
Edit Based on comment - to serve swagger json on a custom route:
// Enable middleware to serve generated Swagger as a JSON endpoint on a custom endpoint
app.UseSwagger(c => c.RouteTemplate = "custom/swagger/{documentName}/swagger.json");
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
// Using custom endpoint defined above
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/custom/swagger/v1/swagger.json", "YourApp API V1");
});
If you need to serve SwaggerUI on a custom route as well, then:
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
// Using custom endpoint defined above
// And serving UI on a custom route
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/custom/swagger/v1/swagger.json", "YourApp API V1");
c.RoutePrefix = "custom"; // serves UI on http://{domain}:{port}/custom/
});
I suggest you to perform the two next steps.
First, open your project web.config and enable stdoutLogEnabled. (Remember to create the folder logs on your application folder and give it proper permissions)
Second, make sure you're doing the right configuration. (https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger)
Note: The first step is going to give you more details about the error you're facing.
In my case the issue was the virtual directory which I fixed by adding a relative path(../). In any case make sure you setup ConfigureServices first, then when Configure make sure everything is in order, UseSwagger should be before UseMvc and at the end UseSwaggerUI
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info { Title = "Utility", Version = "v1" });
});
// initialize configuration
var conf = new ConfigurationHelper(Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath);
Configuration = conf.Configuration; // just in case
// inject the RestApiWrapperService as singleton into the services configuration
var restService = new RestApiWrapperService(conf);
services.AddSingleton<IRestApiWrapperService>(restService);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseSwagger();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
// app.UseMvc();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.UseSwaggerUI(s => {
s.RoutePrefix = "help";
s.SwaggerEndpoint("../swagger/v1/swagger.json", "Utility");
s.InjectStylesheet("../css/swagger.min.css");
});
Change the following on your startup.cs class:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyService.API v1");
});
To
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/MyWebsiteName/swagger/v1/swagger.json",
"MyService.API v1");
});
[MyWebsiteName] being the name of application configured in IIS.
I happened to have a simple copy paste mistake!
see the first line in below code, the if statement env.IsDevelopment() is causing this section to not run when deployed to IIS. One option is to comment it out!
//if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger(c =>
{
c.RouteTemplate = "swagger/{documentName}/swagger.json";
});
app.UseSwaggerUI(c => {
c.RoutePrefix = "swagger";
c.SwaggerEndpoint("/swagger/v1/swagger.json", "StockOps.WebAPI v1");
});
}

Resources