14

I have added the apple-app-site-association file to the root of a website, but IIS is not delivering the file.

What is the best way to make the server serve this specific file without a file extension? Is there a way within a web.config to explicitly say "serve this file"?

ToddBFisher
  • 11,370
  • 8
  • 38
  • 54

7 Answers7

36

I was having the same issue and found this amazing post:

Serving apple-app-site-association from IIS IIS only serves files of known types, defined by their file extension. Since apple-app-site-association doesn’t include a file extention, IIS throws a 404 error, when I try to open it with a browser. I fixed this by adding a mimeMap in the web.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <staticContent>
      <!-- required for apple-app-site-association: -->
      <mimeMap fileExtension="." mimeType="application/json" />
    </staticContent>
  </system.webServer>
</configuration>

If the above solution does not work, then add the following rule Create a rule in the "web.config" file, which will provide the JSON value when the Applebot robot crawls your site for the apple association

<rewrite>
  <rules>
    <rule name="apple_json_file">
                <match url="^apple-app-site-association" />
                <action type="Rewrite" url="apple-app-site-association.json" />
            </rule>
  </rules>

</rewrite>

Add this section in system.webServer

nullromo
  • 2,165
  • 2
  • 18
  • 39
mogile_oli
  • 2,148
  • 2
  • 21
  • 21
  • 2
    Better put this `system.webServer` node under a `` node to restrict this only to this file and avoid serving any other extension less file. – Frédéric Apr 07 '21 at 09:36
3

As explained by this answer, for security reasons, IIS only serves known file types, and uses the file extension to infer the file type. You can declare a file type for extension-less files, allowing to serve them.

But this causes the server to serve any extension-less file, which could cause unexpected files to get served to anyone, including robots probing for sensitive files incorrectly protected.

The solution explained by previously linked answer can be restricted to only that apple file. Better restrict it. Use a location node for this.
By the way, consider adjusting the caching policy for this file, if your default one is not suitable, especially if your server is behind a CDN.

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  ...

  <location path="apple-app-site-association">
    <system.webServer>
      <staticContent>
        <mimeMap fileExtension="." mimeType="application/json" />
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="08:00:00" cacheControlCustom="public" />
      </staticContent>
    </system.webServer>
  </location>

  ...

</configuration>
Frédéric
  • 9,364
  • 3
  • 62
  • 112
  • How would you go about this when the `apple-app-site-association` file is inside of the `.well-known` folder? I'm currently facing this issue, since I can't give up the path of `.well-known/apple-app-site-association` the dot here seems the IIS server to give an error – Damien Brils May 17 '21 at 13:41
  • 2
    You can drop a web.config file in any folder you like. So just take the example above without the lines with three dots, put it in a web.config file inside the `.well-known` folder. This trouble already has its own [question and answer](/q/39365605/1178314). – Frédéric May 17 '21 at 22:20
  • Thanks for the suggestion! I indeed got it to work with a web.config file in the .well-known directory. Many thanks :) – Damien Brils May 18 '21 at 12:17
2

Not my preferred solution, but in leu of DeyaEldeen's comment, the way I met many of our needs was to use the meta tag approach instead (within the <head> tag of the page):

<meta name="apple-itunes-app" content="app-id=5555555555">

This makes is so that whenever any users on iOS browse to the site, they are presented with a "view in app store" popup at the top of the page. Once they press on the popup, they get directed to the app store.

See Apple's docs for Smart App Banners.

Hopefully this helps some people with similar needs.

ToddBFisher
  • 11,370
  • 8
  • 38
  • 54
1

To add to the solutions provided by mogile_oli solution and Frédéric solution a little more configuration is required when using IIS configured for a Net.Core site.

TLDR: Remove aspNetCore handler in the .well-known/web.config and apply existing solution by either mogile_oli or Frédéric

One solution is to place the .well-known folder in the wwwroot folder as suggested here. However this either means making the apple-app-site-association part of your .Net Core project or manually adding this after any publish update. You then make the MIME changes mentioned by mogile_oli or Frédéric

Another solution is to configure static files within the .Net Core app's startup class then the folder/files can live outside of the .Net Core project. This has the downside that this would require a rebuild of the application if you want to make any directory changes.

The solution we opted for doesn't require the .Net Core app to have any knowledge of the .well-known folder.

  1. If you don't have it already create a .well-known folder in the root of the IIS site folder.
  2. Add your apple-app-site-association (and if you doing the equivalent for android your assetlinks.json file too).
  3. Add a web.config file to the `.well-known' folder with the following:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <authorization>
            <allow users="*" />
        </authorization>
    </system.web>
    <system.webServer>
        <staticContent>
            <mimeMap fileExtension="." mimeType="application/json" />
            <!-- Only required for assetlinks.json if your IIS version doesn't already have .json defined -->
            <!-- <mimeMap fileExtension=".json" mimeType="application/json" /> -->
        </staticContent>
        <handlers>
            <!-- Assumes that you have the handler in your root web.config called aspNetCore. Change to match your configuration -->
            <remove name="aspNetCore" />
        </handlers>
    </system.webServer>
</configuration>
  1. This code snippet stops the .Net Core app handling the .well-known folder and then we are free to configure it as per the previous solution by mogile_oli. (As an added bonus if you are adding assetlinks.json and using an older IIS version you need to add a mimeMap for .json files as well).

  2. (Optional) The code snippet above has applied to the entire .well-known folder and as mentioned by Frédéric this can pose a security risk (especially if we have other files in the .well-known folder). We can transform the above to make use of Frédéric's location recommendation:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <authorization>
            <allow users="*" />
        </authorization>
    </system.web>
    <location path="apple-app-site-association">
        <system.webServer>
            <staticContent>
                <mimeMap fileExtension="." mimeType="application/json" />
            </staticContent>
            <handlers>
                <remove name="aspNetCore" />
            </handlers>
        </system.webServer>
    </location>
    <!-- Only required for assetlinks.json -->
    <location path="assetlinks.json">
        <system.webServer>
            <!-- Only required if your IIS version doesn't already have .json defined -->
            <!-- <staticContent>
                <mimeMap fileExtension=".json" mimeType="application/json" />
            </staticContent> -->
            <handlers>
                <remove name="aspNetCore" />
            </handlers>
        </system.webServer>
    </location>
</configuration>

Hope this helps anyone in a similar situation as it took us a lot of trial and error.

afk013
  • 11
  • 1
  • 3
0

Why

For security reasons, IIS cannot allow browsing any file. Imaging, for example, web.config.

How to

The quickest way is to add the file type to the known types by its extension:

Open IIS Manager -> Sites -> Your Web Site -> MIME TYPES -> Add...
    File name extension=.
    MIME type=application/json
-> OK

Now it works.

Community
  • 1
  • 1
epox
  • 9,236
  • 1
  • 55
  • 38
0

I think giving blanket setting for just one file is not good. I have used following approach.

<httpErrors errorMode="Custom">
      <remove statusCode="404"/>
      <error statusCode="404" path="/PageNotFound.aspx" responseMode="ExecuteURL"/>
    </httpErrors>

In that handler I check for specific file request and do rersponse.write the json content to be served.

so the server setting is not compromised.

if(Request.Url.ToString().ToLower().EndsWith("/apple-app-site-association"))
        {
            Response.Write(File.ReadAllText("/apple-app-site-association"));
            Response.ContentType = "text/json";
            Response.Flush();
            Response.End();
        }
0

In my case, 500 Internal server error was coming while hosting the virtual directory on iis server. It got fixed by using below configuration in web.config file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
    <staticContent>
        <mimeMap fileExtension="." mimeType="application/json" />
    </staticContent>
    <urlCompression doStaticCompression="false" doDynamicCompression="false" />
    <validation validateIntegratedModeConfiguration="false" />
</system.webServer>
ArjunArora
  • 986
  • 3
  • 12
  • 27