Azure App Services ฟ้อง 404 (Not Found)

นำโปรเจ็กส์ที่สร้างด้วย Bookdown ขึ้น Azure App Services (Stack=.Net, .Net version=.Net 6) แล้วกล่อง Search ใช้งานไม่ได้ ทั้งที่ตอนพัฒนาก็รันด้วย RStudio แล้วใช้งานกล่อง Search เพื่อทำการค้นหาได้ปกติดี

เลยลอง F12 ดูที่ Console ก็เจอว่า search_index.json 404 (Not Found) ทั้งที่ไฟล์ก็มีอยู่

ลองค้น google ดูจนไปเจอกระทู้นี้ javascript – Getting “404 not found” on doing a GET on local file in Azure web app – Stack Overflow อาการเหมือนกันคือมีปัญหาว่าเรียกไฟล์ javascript จากที่อื่นได้ แต่เรียกไฟล์ javascript ที่อยู่ใน local ไม่ได้

ทางแก้คือสร้างไฟล์ web.config ตามนี้

<?xml version="1.0"?>
<configuration>
    <system.webServer>
        <staticContent>
            <mimeMap fileExtension=".json" mimeType="application/json" />
     </staticContent>
    </system.webServer>
</configuration>

แล้วเอาไปวางไว้ที่ /site/wwwroot

ลองเรียกเว็บอีกที ก็ใช้ได้ละ

Azure App Service

Azure App Service is an HTTP-based service for hosting web applications, REST APIs, and mobile back ends. You can develop in your favorite programming language, be it .NET, .NET Core, Java, Ruby, Node.js, PHP, or Python. Applications run and scale with ease on both Windows and Linux-based environments.

Built-in auto scale support

Baked into Azure App Service is the ability to scale up/down or scale out/in. Depending on the usage of the web app, you can scale the resources of the underlying machine that is hosting your web app up/down . Resources include the number of cores or the amount of RAM available. Scaling out/in is the ability to increase, or decrease, the number of machine instances that are running your web app.

Continuous integration/deployment support

The Azure portal provides out-of-the-box continuous integration and deployment with Azure DevOps, GitHub, Bitbucket, FTP, or a local Git repository on your development machine. Connect your web app with any of the above sources and App Service will do the rest for you by auto-syncing code and any future changes on the code into the web app.

Deployment slots

When you deploy your web app, web app on Linux, mobile back end, or API app to Azure App Service, you can use a separate deployment slot instead of the default production slot when you’re running in the Standard, Premium, or Isolated App Service plan tier. Deployment slots are live apps with their own host names. App content and configurations elements can be swapped between two deployment slots, including the production slot.

App Service on Linux

App Service can also host web apps natively on Linux for supported application stacks. It can also run custom Linux containers (also known as Web App for Containers). App Service on Linux supports a number of language specific built-in images. Just deploy your code. Supported languages include: Node.js, Java (JRE 8 & JRE 11), PHP, Python, .NET Core, and Ruby. If the runtime your application requires is not supported in the built-in images, you can deploy it with a custom container.

The languages, and their supported versions, are updated on a regular basis. You can retrieve the current list by using the following command in the Cloud Shell.

> az webapp list-runtimes --os-type linux
[
  "DOTNETCORE:7.0",
  "DOTNETCORE:6.0",
  "DOTNETCORE:3.1",
  "NODE:16-lts",
  "NODE:14-lts",
  "PYTHON:3.9",
  "PYTHON:3.8",
  "PYTHON:3.7",
  "PHP:8.0",
  "PHP:7.4",
  "RUBY:2.7",
  "JAVA:11-java11",
  "JAVA:8-jre8",
  "JBOSSEAP:7-java11",
  "JBOSSEAP:7-java8",
  "TOMCAT:10.0-java11",
  "TOMCAT:10.0-jre8",
  "TOMCAT:9.0-java11",
  "TOMCAT:9.0-jre8",
  "TOMCAT:8.5-java11",
  "TOMCAT:8.5-jre8"
]

App Service on Windows

> az webapp list-runtimes --os-type windows
[
  "dotnet:7",
  "dotnet:6",
  "DOTNETCORE:3.1",
  "ASPNET:V4.8",
  "ASPNET:V3.5",
  "NODE:16LTS",
  "NODE:14LTS",
  "PHP:7.4",
  "java:1.8:Java SE:8",
  "java:11:Java SE:11",
  "java:1.8:TOMCAT:10.0",
  "java:11:TOMCAT:10.0",
  "java:1.8:TOMCAT:9.0",
  "java:11:TOMCAT:9.0",
  "java:1.8:TOMCAT:8.5",
  "java:11:TOMCAT:8.5"
]

Limitations

  • App Service on Linux is not supported on Shared pricing tier.
  • You can’t mix Windows and Linux apps in the same App Service plan.
  • The Azure portal shows only features that currently work for Linux apps. As features are enabled, they’re activated on the portal.

Azure App Service plans

In App Service, an app (Web Apps, API Apps, or Mobile Apps) always runs in an App Service plan. An App Service plan defines a set of compute resources for a web app to run. One or more apps can be configured to run on the same computing resources (or in the same App Service plan). In addition, Azure Functions also has the option of running in an App Service plan.

When you create an App Service plan in a certain region (for example, West Europe), a set of compute resources is created for that plan in that region. Whatever apps you put into this App Service plan run on these compute resources as defined by your App Service plan. Each App Service plan defines:

  • Region (West US, East US, etc.)
  • Number of VM instances
  • Size of VM instances (Small, Medium, Large)
  • Pricing tier (Free, Shared, Basic, Standard, Premium, PremiumV2, PremiumV3, Isolated)

The pricing tier of an App Service plan determines what App Service features you get and how much you pay for the plan. There are a few categories of pricing tiers:

  • Shared compute: Both Free and Shared share the resource pools of your apps with the apps of other customers. These tiers allocate CPU quotas to each app that runs on the shared resources, and the resources can’t scale out.
  • Dedicated compute: The BasicStandardPremiumPremiumV2, and PremiumV3 tiers run apps on dedicated Azure VMs. Only apps in the same App Service plan share the same compute resources. The higher the tier, the more VM instances are available to you for scale-out.
  • Isolated: This tier runs dedicated Azure VMs on dedicated Azure Virtual Networks. It provides network isolation on top of compute isolation to your apps. It provides the maximum scale-out capabilities.
  • Consumption: This tier is only available to function apps. It scales the functions dynamically depending on workload.

Deploy to App Service

Every development team has unique requirements that can make implementing an efficient deployment pipeline difficult on any cloud service. App Service supports both automated and manual deployment.

Automated deployment

Automated deployment, or continuous integration, is a process used to push out new features and bug fixes in a fast and repetitive pattern with minimal impact on end users.

Azure supports automated deployment directly from several sources. The following options are available:

  • Azure DevOps: You can push your code to Azure DevOps, build your code in the cloud, run the tests, generate a release from the code, and finally, push your code to an Azure Web App.
  • GitHub: Azure supports automated deployment directly from GitHub. When you connect your GitHub repository to Azure for automated deployment, any changes you push to your production branch on GitHub will be automatically deployed for you.
  • Bitbucket: With its similarities to GitHub, you can configure an automated deployment with Bitbucket.

Manual deployment

There are a few options that you can use to manually push your code to Azure:

  • Git: App Service web apps feature a Git URL that you can add as a remote repository. Pushing to the remote repository will deploy your app.
  • CLIwebapp up is a feature of the az command-line interface that packages your app and deploys it. Unlike other deployment methods, az webapp up can create a new App Service web app for you if you haven’t already created one.
  • Zip deploy: Use curl or a similar HTTP utility to send a ZIP of your application files to App Service.
  • FTP/S: FTP or FTPS is a traditional way of pushing your code to many hosting environments, including App Service.

Use deployment slots

Whenever possible, use deployment slots when deploying a new production build. When using a Standard App Service Plan tier or better, you can deploy your app to a staging environment and then swap your staging and production slots. The swap operation warms up the necessary worker instances to match your production scale, thus eliminating downtime.

Authentication and Authorization in App Service

Azure App Service provides built-in authentication and authorization support, so you can sign in users and access data by writing minimal or no code in your web app, API, and mobile back end, and also Azure Functions.

Why use the built-in authentication?

You’re not required to use App Service for authentication and authorization. Many web frameworks are bundled with security features, and you can use them if you like. If you need more flexibility than App Service provides, you can also write your own utilities.

The built-in authentication feature for App Service and Azure Functions can save you time and effort by providing out-of-the-box authentication with federated identity providers, allowing you to focus on the rest of your application.

  • Azure App Service allows you to integrate a variety of auth capabilities into your web app or API without implementing them yourself.
  • It’s built directly into the platform and doesn’t require any particular language, SDK, security expertise, or even any code to utilize.
  • You can integrate with multiple login providers. For example, Azure AD, Facebook, Google, Twitter.

Identity providers

App Service uses federated identity, in which a third-party identity provider manages the user identities and authentication flow for you. The following identity providers are available by default:

ProviderSign-in endpointHow-To guidance
Microsoft Identity Platform/.auth/login/aadApp Service Microsoft Identity Platform login
Facebook/.auth/login/facebookApp Service Facebook login
Google/.auth/login/googleApp Service Google login
Twitter/.auth/login/twitterApp Service Twitter login
Any OpenID Connect provider/.auth/login/<providerName>App Service OpenID Connect login

When you enable authentication and authorization with one of these providers, its sign-in endpoint is available for user authentication and for validation of authentication tokens from the provider. You can provide your users with any number of these sign-in options.

How it works

The authentication and authorization module runs in the same sandbox as your application code. When it’s enabled, every incoming HTTP request passes through it before being handled by your application code. This module handles several things for your app:

  • Authenticates users with the specified provider
  • Validates, stores, and refreshes tokens
  • Manages the authenticated session
  • Injects identity information into request headers

The module runs separately from your application code and is configured using app settings. No SDKs, specific languages, or changes to your application code are required.

 Note

In Linux and containers the authentication and authorization module runs in a separate container, isolated from your application code. Because it does not run in-process, no direct integration with specific language frameworks is possible.

Authentication flow

The authentication flow is the same for all providers, but differs depending on whether you want to sign in with the provider’s SDK.

  • Without provider SDK: The application delegates federated sign-in to App Service. This is typically the case with browser apps, which can present the provider’s login page to the user. The server code manages the sign-in process, so it is also called server-directed flow or server flow.
  • With provider SDK: The application signs users in to the provider manually and then submits the authentication token to App Service for validation. This is typically the case with browser-less apps, which can’t present the provider’s sign-in page to the user. The application code manages the sign-in process, so it is also called client-directed flow or client flow. This applies to REST APIs, Azure Functions, JavaScript browser clients, and native mobile apps that sign users in using the provider’s SDK.

The table below shows the steps of the authentication flow.

StepWithout provider SDKWith provider SDK
Sign user inRedirects client to /.auth/login/<provider>.Client code signs user in directly with provider’s SDK and receives an authentication token. For information, see the provider’s documentation.
Post-authenticationProvider redirects client to /.auth/login/<provider>/callback.Client code posts token from provider to /.auth/login/<provider> for validation.
Establish authenticated sessionApp Service adds authenticated cookie to response.App Service returns its own authentication token to client code.
Serve authenticated contentClient includes authentication cookie in subsequent requests (automatically handled by browser).Client code presents authentication token in X-ZUMO-AUTH header (automatically handled by Mobile Apps client SDKs).

For client browsers, App Service can automatically direct all unauthenticated users to /.auth/login/<provider>. You can also present users with one or more /.auth/login/<provider> links to sign in to your app using their provider of choice.

Authorization behavior

In the Azure portal, you can configure App Service with a number of behaviors when an incoming request is not authenticated.

  • Allow unauthenticated requests: This option defers authorization of unauthenticated traffic to your application code. For authenticated requests, App Service also passes along authentication information in the HTTP headers.This option provides more flexibility in handling anonymous requests. It lets you present multiple sign-in providers to your users.
  • Require authentication: This option will reject any unauthenticated traffic to your application. This rejection can be a redirect action to one of the configured identity providers. In these cases, a browser client is redirected to /.auth/login/<provider> for the provider you choose. If the anonymous request comes from a native mobile app, the returned response is an HTTP 401 Unauthorized. You can also configure the rejection to be an HTTP 401 Unauthorized or HTTP 403 Forbidden for all requests.