I am facing an issue with authenticating my SPFx webpart against an Azure AD backed Web API. What I have done so far is
- Created a ASP.NET WEB API 2 project. Added OWIN and configured CORS and OIDC in the pipeline.
- This works perfectly well when I try to authenticate via the browser by calling the endpoint.
- But when I try to do this via SPFx I get a CORS error that says “Origin null is not allowed”. This is same one a couple of others got here
Some Observations:
- When I deploy my application to an Azure app service and turn on the Authentication from the app service, magically things start to work fine. I am unable to figure out what is it that I am missing in my OIDC configuration that is causing this.
- Also, a bit of network trace showed the following
- Options request is sent to Web server
- Web server responds with 200 OK
- This leads to a redirect 302 to location login.microsoftonline.com with my client ID of the application and other parameters in the querystring.
- This redirect throws a CORS error because the Origin header is null in this case.
Below is how OWIN is setup.
Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var corsPolicy = new CorsPolicy()
{
AllowAnyHeader = true,
AllowAnyMethod = true,
SupportsCredentials = true
};
corsPolicy.Origins.Add("https://m365x081712.sharepoint.com");
CorsOptions corsOptions = new CorsOptions()
{
PolicyProvider = new CorsPolicyProvider()
{
PolicyResolver = context => Task.FromResult(corsPolicy)
}
};
app.UseCors(corsOptions);
ConfigureAuth(app); //Calls within Startup.Auth.cs
ConfigureWebApi(app);
}
}
Startup.Auth.cs
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = "8755bda6-a388-42fc-a8e1-8f2652603334",
Authority = "https://login.microsoftonline.com/m365x081712.onmicrosoft.com/",
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl + "/";
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
return Task.FromResult(0);
}
}
});
}
}
The SPFx (react) code that calls the Web API is
import { AadHttpClient, HttpClientResponse } from '@microsoft/sp-http';
// .. Omitted bunch of unneeded code.
this.context.aadHttpClientFactory
.getClient('8755bda6-a388-42fc-a8e1-8f2652603334')
.then((client: AadHttpClient): void => {
client
.get("https://localhost:44386/api/values", AadHttpClient.configurations.v1,{
credentials:"include", //probably don't need this.
method:"GET"
})
.then((response: HttpClientResponse): Promise<any[]> => {
return response.json();
})
.then((data: any[]): void => {
console.log(data);
});
});