the following components describe my solution in Azure which I want to bring to work:
Client: The clients are common Browsers from anonymous users all over the internet that are making ajax requests to the backend server which is generelly a simple web api which is implemented with .NET Core.
Azure Web App 1: This azure web app is the frontend app consisting of static html and java script files.
Azure Web App 2: This azure web app is the backend app which is implemented in .NET Core and serves the web api interface.
In general, the browser is served with the static content by Azure Web App 1 and wants to execute an Ajax request to the azure Azure Web App 2. This does currently not work because I get a CORS error. Needless to say, because the clients are anonyous browsers, I do not konw their IP addresses.
Can anyone tell me what I have to do in Azure so that this scenario is going to work? I explicitly want to separate the frontend app from the backend app and deploy them independently on different Azure Web Apps. I think this should be a common scenario and hope that there are easy ways to get these scenario work.
Thank you to all the guys who try to help me with this challenge!
Best regards!
As I understand, you want to create a multitier application (screenshots below), in which the API back-end apps can be accessed only from the front-end tier.
You can use combination of networking features available in App Service to accomplish your scenario. Namely, Regional VNET and Service/Private endpoints. With App Service networking features, you can control traffic going to your backend app.
Also, on App Service, you could have those two separate apps in the same App Service Plan (ASP), since you pay only for ASP, saving costs.
-Just to highlight, you can continue to add apps to an existing plan as long as the plan has enough resources to handle the load. The apps in the same App Service plan all share the same compute resource.
Also, see this doc for the flow/process for this setup:
Create two web apps connected securely with Private Endpoint and VNet integration
Referenced from this doc App Service networking features- screenshots and use cases.
I found an easy way to resolve my problem. So for my scenario, I do not need any additional services or components like the Azure application gateway.
My solution is related to https://learn.microsoft.com/de-de/aspnet/core/security/cors?view=aspnetcore-5.0.
First the ASP.NET core web api needs the following Code in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
var origins = new List<string>
{
"https://xxx-apifrontend.blob.core.windows.net/",
"https://127.0.0.1:5500",
"https://localhost:5500"
};
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins(origins.ToArray())
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed((host) => true);
});
});
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
...
}
But in Azure, this is still not enough. Secondly, the allowed origins must also be declared in the CORS section of the Azure web app. I did this through the Azure Portal:
Related
I'm facing issue with my multiple project solution in .net core webAPI. I've gatewayAPI which internally makes call to different microservices via http call.
Gateway API URI exposed to outer world which has domain as azure app name but the internal calls from gateway to microservices are configured with http://localhost:5001/{apiEndPoint} which is working fine in my local machine but after deploying it on azure app service I'm getting below error:
PostToServer call URL:'http://localhost:5001/api/authservice/authenticate' with Exception message An attempt was made to access a socket in a way forbidden by its access permissions. (localhost:5001).
Can someone please help me with this, I'm new to azure and learning on my own but could not find any solution for this yet.
PS: After going through some YouTube videos and blogs I got to know we have to use AKS but I'm not confident in that.
Would really appreciate any help on this issue.
The Gateway API you deployed to azure app service, it doesn't support custom port usage for 5001. Azure App Service only supports port 80|443(HTTP|HTTPS).
If you must use multiple ports in your actual project, then it is recommended to check whether Azure Cloud Service meets your needs. But it not the best choice.
The Best Practice:
Microservices architecture design
In short,create a Azure Gateway service, and your other microservice can be deployed in any where.(azure app service, vm or aks)
You just make sure you can access your microservices in your internal or public network environment.
If you're just learning, or the app isn't actually used by a lot of users, you can try the following suggestions:
Use SignalR (not azure signalr) to replace the websocket in your current project.
You have on azure app service, you can deploy your Gateway API Application to app service, and your other microservices can be deployed to Virtual Application in azure app service.
I've a conceptual question about Static web site on Storage Account & App Service.
My team have develop an Angular10 + ASP.NET Core (API) application. Our frontend (Angular10) only consumes our API , so the availability of our app depends on the availability of both, frontend + backend (our API will NOT be consumed by any other app). We don't have any latence issue or requirement as our final users are all in the same region. Our app must be consumed through HTTPS and with a specific name (CNAME).
When we deploy the app to Azure, my team decide to deploy it separately using a Store Account as static web site for Angular 10 and an AppService for the API as backend of our App.
As far I see on MS docs (here is the related article):
"App Service Static Web Apps is a great alternative to Azure Storage static website hosting and is also appropriate in cases where you don't require a web server to render content"
Because of we currently need an AppService to render content, i have some questions:
The app works but, is a correct arquitectural approach or is better only publish our app to an AppService?
There are any security/cost related/whatever topic that makes StaticWebSite + AppService approach better than only AppService deploy?
I think that this approach does not give us any facility or advantage. Instead of this, we have to configure more things on Azure to connect through SSL and to give a CNAME to our app and AppService deploy.
Please, can you give me your oppinion?
Thanks in advance
Best regards
Luis
The best approach would be to split out the SPA and API and host them separately. This creates a loose coupling between the applications giving you more flexibility around performance, scalability, and deployment.
The .NET Core API could be hosted on an Azure App Service, or could it even be refactored into running as a set of serverless Azure Functions? Converting it into functions would allow for auto scaling and a likely reduction in cost as you only pay when the function is running. It depends what the API methods are actually doing.
The SPA could be hosted as a static web site in a storage account blob container, and with a CDN endpoint mapped to it you can set it up to expose the SPA using HTTPS on a custom domain. Alternatively you could use an Azure Static Web App (although this is still in preview). This simplifies the deployment of SPAs as it will connect to your code repo and build and deploy the SPA for you when changes are committed to the repo.
That would of course mean configuring two separate CNAME subdomain records (assuming you wanted to the API to have a custom domain name), but that's not a big deal and ultimately a clearer separation on concerns.
Static Web Hosting: https://learn.microsoft.com/en-gb/azure/storage/blobs/storage-blob-static-website-how-to
Azure Static Web Apps: https://learn.microsoft.com/en-gb/azure/static-web-apps/overview
Static Hosting with Azure CDN: https://www.red-gate.com/simple-talk/cloud/azure/static-hosting-with-azure-blob-storage-and-azure-cdn/
Hosting option depends on your requirements.
Use case for using Static web site on Storage Account is a need to manipulate or process data on the server side, simply call the relevant managed Azure service like Azure Cognitive Services or leverage a web server of your own hosted on Azure Functions.
https://azure.microsoft.com/en-us/blog/static-websites-on-azure-storage-now-generally-available/
Your are Static web site makes a call to Azure WebApp API, so you should have Azure WebApp Plan.
Azure WebApp Plan can host both API and Static web site. Benefits of such scenario are:
Reduce cost as you can host multiple WebApps in same Azure WebApp Plan.
Azure WebApp gives you more hosting features versus Storage Account
Deployment can be implemented in same way for both Static web site and API
I would to host two ASP.NET Core Applications, a Web API and a Blazor Server App, but I searched in the internet and the answers that I founded only target to a different path inside of one application, that's not my case. I would to use they like a sub-address of the same Azure Web App for example: www.example.com and www.example.com/api where each one will be a different .NET Core application. So I suspect that I'll need to create two Azure App Services and try to communicate they both, but maybe the structured that I wonder won't work in this way, it's that right? How I can do this?
I have the same setup as you; an ASP.NET Core web API, and a Blazor Server Side app.
As you want to use the same domain for both services, you would have to use Azure API Management or some other proxy if you were to route requests to two different Azure App Services.
An easier option is to deploy both services to the same App Service, but as different virtual applications. You publish your Blazor app as normal, but for the Web API you would publish to a new virtual application /api.
To enable this virtual application, navigate to Configuration and then Path mappings in your App Service. Here you already have the default virtual application / pointing to site\wwwroot. You then add another virtual application named /api pointing to site\wwwroot\api:
When adding the virtual application, remember to remove checkbox for Directory (making it a virtual application instead), and optionally enable Preload:
If you publish your app using Azure DevOps Pipeline, it has an option to specify virtual application if another than default should be used.
You can now navigate to your two different URLs and hit each service. Note that when developing your Web API, you should not add api to your controllers routes, as this virtual application does that for you.
my question is, how can I restrict access to my Azure WebApp/WebApi from internet.
For example the following architecture:
One WebApi (Backend)
One WebApp (Frontend)
The user should invoke the url of the WebApp (Frontend) but it should not be possible to invoke the url of the WebApi from the internet.
Ok I know I can restrict access in the WebApis through IP-Restrictions in the web.config. But is there no other solution?
I thought of something like this:
Azure WebApi and Firewall
Is this possible and what resources I exactly need?
the Api should not have an external IP/DNS, deny all request coming from internet
According to your description, you would not access the web api which is backend through url and do not want to use authentication filters in web api.
Actually, you could configure your router configuration to achieve it.
You could use the following code in Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
You can accomplish this by creating an internally load balanced App Service Environment. This is a pricey option, but it allows you to create an App Service App entirely within your VNET, and configure your load balancer to deny all public requests to the backend API.
If you're just looking to secure access to the backend API, I would suggest using Service Principle Auth.
Enabling Auth on an App Service App
Configuring service principle auth
In a typical 3-Tier web app, you run web servers in public subnet, while app tier lives in private subnet. Is it possible to run similar architecture with Azure Web apps and Api apps?
I guess you can run Asp.NET Core Web App in Azure Web App and Deploy AspNet Core Web Api to Azure Api App, then make Api end point private so only Web app can talk to it? I see options like Google, Facebook et. as auth providers. Is that what you have to do to make API private?
D.
If you want that level of isolation, one (although expensive) option is an App Service Environment (ASE). Link to docs: https://learn.microsoft.com/en-us/azure/app-service-web/app-service-app-service-environment-intro
App Service Environments are ideal for application workloads requiring:
Very high scale
Isolation and secure network access
The public environment where you deploy by default is public. Your endpoints will be accessible to anyone anywhere, and it is up to your app to do the filtering. This can be done, e.g. through static IP address security settings in Web.config. The problem with that is that even then you can't know for sure what IP address your front-end will use for communication. There are multiple possible addresses it may use for outbound traffic, and those are subject to possible change.
You can see an example of IP restrictions here: restricting IP security
Of course you should also have authentication set up on your API. Documentation links:
https://learn.microsoft.com/en-us/azure/app-service/app-service-authentication-overview
https://learn.microsoft.com/en-us/azure/app-service-api/app-service-api-authentication
In line with what #juunas said above and a slight variant is to introduce Azure API Management Gateway in between Azure web app and Azure Api app. In standard tier API Gateway the IP address is fixed and doesn't change and you can use the API Gateway address in Azure API App web.config to whitelist.