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.