I have a default react SPA page made with visual studio 2022 and im using windows authentication. My app will run only on an IIS hosted intranet app.
At my Program.cs, i have configured the authentication and authorization:
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication();
builder.Services.AddAuthorization();
builder.Services.AddHttpContextAccessor();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = NegotiateDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = NegotiateDefaults.AuthenticationScheme;
}).AddNegotiate();
app.UseAuthentication();
app.UseAuthorization();
To test, i created a method app.Use to capture the username, and when i run it with the IISExpress profile, i can get the logged windows user successfully at the homepage The breakpoint on the if clause is hit in every request on the application
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
await context.ChallengeAsync();
await next();
}
else
{
await next();
}
});
But when i call an endpoint to the example "weatherForecastcontroller" or i dont get the logged user on the httpContext, or the page sends me an Error 401.2 - Unauthorized. I also set up the credentials on the fetch call to "include"
async populateWeatherData() {
const response = await fetch('weatherforecast', { "credentials": "include" });
const data = await response.json();
this.setState({ forecasts: data, loading: false });
}
I also have set the launchsettings.json to accept only the windows authentication
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:53168",
"sslPort": 44381
}
Tried also to change the InProcess to OutOfProcess build and the same error occurs
Also, i created an mini web.config, to setup the security tag to allow windows authentication and tried to modiffy the .vs folder .vs<app>\config\applicationhost.config to change de windows and anonymous auth configs
If i use an MVC project on the same machine, it works like a charm, i think there's an proxy or another thing on SPAProxy that bugs things up
What am I missing to successfully get those credentials, any tips or workarounds?
Well, after many googling and testing, i came with a workaround:
The http-proxy-middleware mix up the request headers, and .Net Core does not let authorize, whathever i do;
Configure Authentication and enable cors in Program.cs, allowing it in all application, or just in the controllers that needs to be authenticated. The url in withorigins is the react development server. For a real application, use appSettings.<Development/Staging/Production>.json approach and include that variable as an array of strings of adresses. For debug in local IIS and in production environment, install the IIS Cors Module, downloading it by Microsoft
Program.cs
builder.Services.AddCors(options =>
{
options.AddPolicy("Padrao", builder =>
{
builder
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.WithOrigins("https://localhost:44431");
});
});
builder.Services.AddAuthentication(configureOptions =>
{
configureOptions.DefaultAuthenticateScheme = NegotiateDefaults.AuthenticationScheme;
configureOptions.DefaultChallengeScheme = NegotiateDefaults.AuthenticationScheme;
}).AddNegotiate();
builder.Services.AddAuthorization();
var app = builder.Build();
.env.development
PORT=44431
HTTPS=true
REACT_APP_ASPNETCORE_URLS="https://localhost:44375/"
.env
REACT_APP_ASPNETCORE_URLS="https://localhost/testreact/"
Use the fetch with credentials and keep-alive headers
async populateWeatherData() {
const response = await fetch(process.env.REACT_APP_ASPNETCORE_URLS +'weatherforecast', {
method: "GET",
mode:'cors',
credentials: 'include',
headers: {
"Connection": 'keep-alive',
}
});
const data = await response.json();
this.setState({ forecasts: data, loading: false });}
Allow windows authentication and disable anonymous authentication. You will need to run the app as IISExpress profile, or create a IIS profile to debug, change it in launchsettings.json
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iis": {
"applicationUrl": "http://localhost/testereact",
"sslPort": 443
},
"iisExpress": {
"applicationUrl": "http://localhost:43938",
"sslPort": 44375
}
To allow Vs2022 run in Local IIS, install de IIS Integration on the Visual Studio Installer. With this approach, you will need to call npm start in your /Clientapp by the Powershell command prompt (i didn't make it do call by himself)
I still do not tested this approach in production environment with a real application, but this solves the issue