I've been following the doc here that uses an iframe to handle authentication issues. This works fine for GET operations, but I'm getting a 403.6 error when POSTing.

The code is running in the sharepoint workbench https://someserver.sharepoint.com/_layouts/15/workbench.aspx

The code in the SPFX part is calling a Web API that been deployed to Azure, which is secured with Azure AD. Prior to it being in Azure, it worked fine when running from my local machine. The service is at: https://someazuresite.azurewebsites.net/api/test

      ,headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      body: JSON.stringify(formPayload)
    }).then((response: HttpClientResponse): Promise<string> => {
        return response.json();
    }).then((result:string):void =>{
      console.log("post completed: " + result);

The browser (chrome) console shows "403 Forbidden"

The Azure log shows "This generic 403 error means that the authenticated user is not authorized to use the requested resource", and "HTTP Error 403.60 - Forbidden", "You do not have permission to view this directory or page"

I checked the request headers, and I see the authentication cookies.

Any thoughts on why the GET works, but my POST fails?

Edit: I assume my headers are wrong, though sending "application/json;odata=verbose" causes an options request to be sent, which doesn't have the authentication headers, causing a redirect, which then doesn't work.

  • are you testing this out on a developer tenant ? Apr 16, 2018 at 6:34
  • 1
    Testing from the workbench. It is not a developer tenant.
    – Mike2500
    Apr 16, 2018 at 9:56

3 Answers 3


You have to add the correct header to your post method. It's necessary to include the odata-version and the x-http-method.

const itemHeader: any = {
    'Accept': 'application/json;odata=nometadata',
    'Content-type': 'application/json;odata=verbose',
    'odata-version': '',
    "X-HTTP-Method": "POST"
const spHttpClientOptions: ISPHttpClientOptions = {
    "headers": itemHeader,
    "body": JSON.stringify(formPayload)

    .then((response: SPHttpClientResponse) => {
      // Do with the response what you want

Don't forget to include the sp-http library

import { SPHttpClient, SPHttpClientResponse, ISPHttpClientOptions } from '@microsoft/sp-http';
  • 1
    sphttpclient? I thought that was for calls to sharpeoint; the service I'm calling is a web api in azure.This results in "Unable to determine web URL". Using httpclient, changing the content type causes an OPTIONS call, which doesn't include the authentication header, causing the call to fail.
    – Mike2500
    Apr 12, 2018 at 13:25

To me that sounds like a CORS Issue. CORS is a mechanism that allows restricted resources on a web page to be requested from another Domain. You usually have to configure which HTTP-Methods are allowed per Resource and if Authentication is allowed to be passed to that Domain.

Here is the Documentation for WebAPI CORS.


Thanks for the suggestions. It turns out that the easy way of configuring Azure AD authentication adds some additional middleware that checks for Cross Site Forgery Requests. The error showed access denied, but when I changed logging in the azure portal to verbose, the CSFR error showed up. To my knowledge, there is no way to modify this behavior. The solution is to NOT follow the common tutorials and documentation, and do not use the "App Service Authentication" feature from the Azure portal. Instead, configure Authentication from within the App itself (as-in, using visual studio to configure authentication, either via the new project wizard, or add the necessary pieces if you created the project without that option.) Your app will still be protected via Azure AD, but since you didn't use the easy "App Service Authentication" azure feature, your project won't have the CSFR middleware added, and POSTs to your Web API will work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.