5

I'm attempting to retrieve some data from a custom Azure Function written in C#

[EnableCors]
[FunctionName("Authenticate")]
public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")]HttpRequestMessage req, TraceWriter log)
{
    var privateKey = new SHA512CryptoServiceProvider();
    var res = req.CreateResponse(req.Headers);
    res.Headers.Add("Access-Control-Allow-Credentials", "true");
    res.Headers.Add("Access-Control-Allow-Origin", req.Headers.GetValues("Origin").FirstOrDefault());
    return (IActionResult)res;
}

In the configuration for the Azure Function, I have CORS enabled with one rule (https://localhost:4321). This is the correct URL for my locally hosted SharePoint workbench.

I followed Microsoft's tutorial on this, but I'm getting the following error message:

sp-http.js:1570 Uncaught (in promise) Error: This operation cannot be performed until the AadTokenProvider is initialized.
    at AadTokenProvider.getToken (sp-http.js:1570)
    at sp-http.js:2414
    at ServiceScope.whenFinished (sp-loader-assembly_en-us.js:9861)
    at sp-http.js:2410
    at new Promise (<anonymous>)
    at AadHttpClient.fetch (sp-http.js:2409)
    at AadHttpClient.get (sp-http.js:2433)
    at AdalWebPart.render (AdalWebPart.ts:23)
    at AdalWebPart.BaseClientSideWebPart._renderWithAccessibleTitle (sp-webpart-base.js:1535)
    at sp-webpart-base.js:1369

This is the code I'm using to try to get the data:

export default class AdalWebPart extends BaseClientSideWebPart<IAdalWebPartProps> {
    private authenticationClient: AadHttpClient;

    public render(): void {
        this.context.statusRenderer.displayLoadingIndicator(this.domElement, "Authenticating");

        this.authenticationClient.get(
            "https://morganstestauthfunction.azurewebsites.net/api/Authenticate",
            AadHttpClient.configurations.v1
        ).then(res => console.log(res.json()));
    }

    protected onInit(): Promise<void> {
        this.authenticationClient = new AadHttpClient(this.context.serviceScope, "ae63d423-1028-40bd-9032-bdefce20b82d");
        return Promise.resolve();
    }
}

I've also tried the method suggested in this tutorial from Microsoft

export default class IFrameHandler extends React.Component<any>{
    private remotePartyLoaded: () => void;

    public constructor(public props: any) {
        super(props);
        this.remotePartyLoaded = props.remotePartyLoaded;
    }

    public render() {
        return (
            <iframe
                src={"https://morganstestauthfunction.azurewebsites.net/api/Authenticate"}
                style={{ display: "none" }}
                onLoad={this.remotePartyLoaded.bind(this)}
            />
        )
    }
}


export default class AzureWebPart extends BaseClientSideWebPart<> {

    private azureCallback() {
        this.context.httpClient.get("https://morganstestauthfunction.azurewebsites.net/api/Authenticate",
            HttpClient.configurations.v1, {
                credentials: "include",
            }).then(console.log);
    }


    public render(): void {
        const element: React.ReactElement<any> = React.createElement(
            IFrameHandler,
            {
                remotePartyLoaded: this.azureCallback.bind(this)
            },
        );

        ReactDom.render(element, this.domElement);
    }
}

That method throws this:

Failed to load https://morganstestauthfunction.azurewebsites.net/api/Authenticate: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'https://localhost:4321' is therefore not allowed access.

The eventual end goal is to use this Azure Function to act as an authentication proxy that verifies the identity of a SharePoint user, so I need the function to be integrated with Azure AD.

Morgan Thrapp
  • 9,748
  • 3
  • 46
  • 67
  • 1
    1. For your first error: you need to add JwtAuthentication, similar to this: https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapi 2. If you have not done so, you need to pass "supports_credentials=True" or "CORS_SUPPORTS_CREDENTIALS"=True in your config. 3. This looks like a similar issue. Have you checked out this thread? https://github.com/Azure/azure-functions-host/issues/620 – Marilee Turscak - MSFT Jul 30 '18 at 21:05
  • 1
    For 1, I'm unsure where I would add that. My understanding of an Azure Function was that it was just the route definitions, without any sort of service configuration step (e.g. Setup.cs in ASP.NET Core). For 2, is that at the top level of the function definition file? I didn't see it in the json schema (http://json.schemastore.org/function). Is it part of a nested key? For 3, I have seen the thread. I tried removing all CORS rules and I'm getting that second error, but with a null origin. I don't have any proxies enabled as near as I can tell, so I don't believe that is the issue either. – Morgan Thrapp Jul 30 '18 at 21:53

0 Answers0