Azure / static-web-apps

Azure Static Web Apps. For bugs and feature requests, please create an issue in this repo. For community discussions, latest updates, kindly refer to the Discussions Tab. To know what's new in Static Web Apps, visit https://aka.ms/swa/ThisMonth
https://aka.ms/swa
MIT License
329 stars 56 forks source link

Managed Azure function CORS preflight redirect error after session expiration #1194

Open afreidz opened 1 year ago

afreidz commented 1 year ago

On an azure static web app, using managed azure functions as an api, when I let my app stay open overnight, the next api call to the azure function fails CORS preflight due to the response 302 redirecting to https://identity.2.azurestaticapps.net/.redirect/aad

staticwebapp.config.json

{
  "platform": {
    "apiRuntime": "node:18"
  },
  "routes": [
    {
      "route": "/login",
      "redirect": "/.auth/login/aad"
    },
    {
      "route": "/logout",
      "redirect": "/.auth/logout"
    },
    {
      "route": "/.auth/login/github",
      "statusCode": 404
    },
    {
      "route": "/.auth/login/twitter",
      "statusCode": 404
    },
    {
      "route": "/manifest.json",
      "allowedRoles": ["anonymous"]
    },
    {
      "route": "/sw.js",
      "allowedRoles": ["anonymous"]
    },
    {
      "route": "/icons/*",
      "allowedRoles": ["anonymous"]
    },
    {
      "route": "/*",
      "allowedRoles": ["authenticated"]
    }
  ],
  "responseOverrides": {
    "401": {
      "statusCode": 302,
      "redirect": "/.auth/login/aad?post_login_redirect_uri=.referrer"
    }
  }
}

GItHub Action

name: Azure Static Web Apps CI/CD

on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened, closed]
    branches:
      - main

jobs:
  build_and_deploy_job:
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
    runs-on: ubuntu-latest
    name: Build and Deploy Job
    steps:
      - name: Checkout source code
        uses: actions/checkout@v2
        with:
          submodules: true
      - name: Install Dependencies
        run: npm ci
      - name: Check Source Code
        run: npm run check
      - name: Build
        run: npm run build
      - name: Deploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_XXXXXXXXXXXX }}
          repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
          action: upload
          ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
          # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
          app_location: frontend/serve
          api_location: backend
          skip_app_build: true
          skip_api_build: true
          output_location: ""
          config_file_location: ./
          ###### End of Repository/Build Configurations ######

  close_pull_request_job:
    if: github.event_name == 'pull_request' && github.event.action == 'closed'
    runs-on: ubuntu-latest
    name: Close Pull Request Job
    steps:
      - name: Close Pull Request
        id: closepullrequest
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_WHITE_COAST_00E412210 }}
          action: close

Error Redirected from 'https://XXXXXXX/api/trpc/ZZZZZZ.getByDate?input=%7B%22date%22%3A%222023-06-05%22%7D') from origin 'https://XXXXXXX' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

afreidz commented 1 year ago

i think the issue here is that i am protecting nearly every route using "authenticated" and adding a 401 response override to 302 to the login page. this setup would cover /api/* routes too. so maybe another question is: is there a preferred way to authenticate api calls for azure static web?

jm-lovelace commented 1 year ago

I am also seeing this same behavior. Is there any resolution?

afreidz commented 1 year ago

not that i have seen. i think i had to open the api routes to anonymous traffic and authenticate those requests manually. let me look again.

afreidz commented 1 year ago

yea looks like thats what i did. i have:

{
      "route": "/api/*",
      "allowedRoles": ["anonymous"]
    },

and then i use the header x-ms-client-principal and decode it from base64 to get the authenticated user details in the api. i have NO IDEA if this is secure or if it can be easily spoofed. but for me, it was enough for an internal application. it was less about "authorization" and more about using the user id to get only their associated records from a database. 🤷

jm-lovelace commented 1 year ago

Interesting. Thanks for the info! I'm trying one thing to see if it works: my app was making a request to the API before the initial 302 redirect on the home route, so I'm hoping that if I prevent that from happening it might fix the issue

afreidz commented 1 year ago

no problem! yea i was able to circumvent most scenarios by authenticating on the front-end first before any api calls. where this became an issue for me was: leaving the app running and the session/token eventually hits a timeout. the next action would subsequently require re-logging in. for me, that was another api call that i made when the app was "unbackgrounded" ... that call failed and i had to do some error handling gymnastics to trigger re-authenticating. in essence, the user sees an error modal for a split second before a programmatic refresh that re-auths them. not ideal at all. wish someone would take a look at this!