Question

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

this.props.httpClient.post('https://someazuresite.azurewebsites.net/api/test',HttpClient.configurations.v1,{
      credentials:"include"
      ,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.

Was it helpful?

Solution 3

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.

OTHER TIPS

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)
};

this.props.context.spHttpClient.post(
    'https://someazuresite.azurewebsites.net/api/test',
    SPHttpClient.configurations.v1,
    spHttpClientOptions)
    .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';

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top