How to enable HTTP endpoints for Redirect Url in AzureAD? - asp.net-core

I've got Azure ServiceFabric web-app (AspNetCore 3) hosted over reverse proxy (NGinx). The app use AzureAD (in company) authentication. I've Registered App for the AD and setup Redirect Urls mannually in manifest. After publishing the APP and configuring DNS and reverse proxy I tried to authorize to my app but failed with AADSTS500117: The reply uri specified in the request isn't using a secure scheme.
Is it possible to configure client to allow http redirects?
P.S. As I know Identity Server allows it by configuring DiscoveryPolicy.
P.P.S. You can find more information in my origianl question (see. How to change redirect_uri for Azure AD)

What happens?
when you deploy web apps with a reverse proxy, as is, for instance the case with App Services as Linux containers, your application will be called on an HTTP address, whereas its registered redirect URI in the app registration will be HTTPS.
This means that when a user browses to the web app, they will be redirected to login.microsoftonline.com as expected, but with redirect_uri=http://<your app service name>.azurewebsites.net/signin-oidc instead of redirect_uri=https://<your app service name>.azurewebsites.net/signin-oidc.
How to fix it?
In order to get the right result, the guidance from the ASP.NET Core team for working with proxies is in Configure ASP.NET Core to work with proxy servers and load balancers. You should address the issue centrally by using UseForwardedHeaders to fix the request fields, like scheme.
The container scenario should have been addressed by default in .NET Core 3.0. See Forwarded Headers Middleware Updates in .NET Core 3.0 preview 6. If there are issues with this for you, please contact the ASP .NET Core team https://github.com/dotnet/aspnetcore, as they will be the right team to assist with this.

Related

C# ASP.NET Core IdentityServer4 wrong redirect after login when using HTTPS

I am using IdentityServer4 in my ASP.NET Core (v3) web application. Frontend is Angular8.
Both IdentityServer and my webapp are deployed in an IIS instance, in two web sites.
IdentityServer -> 192.168.100.10:8080 (HTTP) and sso.mycompany.local:8443 (HTTPS)
MyApp -> 192.168.100.10:80 (HTTP) and app.mycompany.local:443 (HTTPS)
When using HTTP (opening the browser on http://192.168.100.10) I can successfully log in via the usual web flow (myapp -> identityserver login page -> callback auth -> my app destination url)
In this scenario the url called by identity server is http://192.168.100.10/connect/authorize/callback?client_id=[....]
(I can see it in Chrome dev console)
When using HTTPS (opening the browser on https://myapp.company.local) the flow is wrong after identityserver auth: in Chrome dev console I see this:
https:///connect/authorize/callback?client_id=[....]
It looks like hostname is missing...
Please notice I am talking about the very same instance of both applications, just bound to different addresses in the same IIS instance (same configurations, same binaries, same frontend)
Issue was inside our application and not inside Identity Server

Azure web app deployed as docker container endless 301 loop

We are trying to migrate our REST Web API from being hosted as a Windows .NET Core 3.1 stacked web app to a containerized web app on Linux on Azure.
So far we have managed to push the image to the Azure Container Registry where it's being automatically picked up and successfully deployed to an App Service. Unfortunately, the app does not properly work yet. When trying to fetch some configuration data from a (anonymous) end-point from our API (GET https://foo.azurewebsites.net/api/configuration), instead of returning the data - as it used to do - I get a 301 (Moved Permanently) status code that points exactly to itself: location: https://foo.azurewebsites.net/api/configuration which leads to redirection loop.
So far I have no idea why I'm getting a 301 and I'm glad for any hints.
Points of interest:
Docker: the base for the image is: mcr.microsoft.com/dotnet/core/aspnet:3.1
Azure: Authentication / Authorization is switched off
Azure: no Front Doors are installed
The app is correctly serving the Swagger UI.
The Docker image works fine locally.
Here's how I solved the problem: it turned out that the cause for the permanent redirect loop was a conjunction of how the proxy works in the Azure deployment (thanks to Jason Pan for pointing me in that direction) and the following code that we had in our Startup:
services.AddControllersWithViews()
.AddMvcOptions(o =>
{
...
o.Filters.Add(new RequireHttpsAttribute { Permanent = true }); // REMOVE THIS LINE
...
});
Once I removed RequireHttpsAttribute filter, the app started working as expected. And since I've configured the TLS/SSL settings to allow HTTPS only, I think it is safe to omit the filter.
UPDATE 2021-01-20
I've just figured out that there's a better way to do this that does not require to remove the RequireHttpsAttribute filter. The core of the problem is that Kestrel does not know that communication is happening over a secure channel as the reverse proxy is forwarding requests over http to Kestrel. So we need to enable the forwarding of headers. For .NET Core 2.x applications this meant to follow the steps explained in Configure ASP.NET Core to work with proxy servers and load balancers. Luckily, for ASP.NET Core 3.x applications there a much more simpler way (that unfortunately is not mentioned in the official docs yet but was part of the preview 6 announcement): simply set the ASPNETCORE_FORWARDEDHEADERS_ENABLED environment variable to true. This can be done the usual way in the Azure portal under Confguration > Application settings:

Host two asp.net core applications on the same Ip and port (localhost:8080 for example)

I have two projects which are ASP.NET CORE servers (1 BackEnd and 1 Identity Server)
I would like the BackEnd to serve both apps on the same port and keep two separately runable projects.
How can I make this possible ? The purpose is to open only one port to the client.
Thanks in advance
I have two projects which are ASP.NET CORE servers (1 BackEnd and 1 Identity Server) I would like the BackEnd to serve both apps on the same port and keep two separately runable projects.
If your App(s) are hosted on IIS, you can try to deploy your BackEnd service and Identity Server in two separate applications under same web site as below.
Please note that the application's path would become part of the site's URL if we create an application in IIS. To make your Apps can work well, you may need to modify some code to include application's path in URL while you configure Identity Server to protect your BackEnd service.
In IIS, you need to set a binding for each web application. Then each web application will respond to requests for the corresponding binding.

Map WebApi directly to the website and not use IIS Application

I have lot of webapis which are developed and deployed independently.
Each API would have routing for ex:
api/FirstApi
api/SecondApi
These will be deployed under www.myapis.com/.
If I create application for each of the api(s) in IIS, I would access the api as follows
www.myapis.com/FirstApiApp/api/FirstApi
but I want to access it as.
EX: www.myapis.com/api/FirstApi
Or: www.myapis.com/api/SecondApi
I want to remove the application FirstApiApp OR SecondApiApp from the url.
Is it possible to configure this pattern in IIS?
You could have the following structure:
c:\inetpub\wwwroot\api\FirstApi
c:\inetpub\wwwroot\api\SecondApi
And then have a website in IIS mapped to c:\inetpub\wwwroot and inside the api folder you have the 2 applications configured like this:
This assumes that you should drop the api/FirstApi routing from your Web APIs and map them to / directly because the first part will be provided by IIS. If you don't do this the request will become www.myapis.com/api/FirstApi/api/FirstApi which is not the goal here.
This being said, personally I would recommend you against doing this. A better approach would be to have a reverse proxy such as nginx or HAProxy in front which will route requests to /api/FirstApi to for example backend_node:8080 and requests to /api/SecondApi to backend_node:8181. This would allow you to deploy your Web APIs in two separate website in IIS listening on two different ports and keep the routing job to the application layer and not the infrastructure.

Web Api hosted on another port on IIS is not accessible

I have two separate projects
MVC Web App
MVC Web API
I have published both on my IIS 7.5
My Web App is hosted on 7172 port
and Web API is hosted on 7171 port
Strangely iam not able to call jquery.ajax() from my web app (7172) to web api (7171) port. It gives me 405 Method not found error code.
But if i write the same jquery.ajax() in my web api project (7171) and call web api method then it work fine and returns data.
I want to call web api from my web app.
Any suggestion would be appreciated.
Thanks in advance.
This has to do with the Same Origin Policy. By default, you can't execute an AJAX call to another domain (both on name, port and protocol).
If you want to enable this you should use Cross-origin resource sharing (CORS). CORS can be used with Web API by installing a (prerelase) NuGet package: Microsoft ASP.NET Web API Cross-Origin Support
This package allows you to configure which domains can call your service. You can find a walk trough here Enabling Cross-Origin Requests in ASP.NET Web API. In essence it comes down to adding attributes to your controllers like this:
[EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", methods: "*")]
You're running into the same-origin/cross-domain security policy. The port used is part of the origin calculation. A bit of Javascript loaded from (say) localhost:80 cannot make an AJAX request to localhost:8080, because the port numbers don't match. The 405 error you're getting is almost certainly coming from your Web App, not the API - check the server logs for the app, and you'll see the ajax hit in there.