We are using ASP.NET Core 3.1 MVC with React 17.0.2. Also, Windows Authentication is used.
By reading this documentation, we've added a proxy file to proxy API calls to ASP.NET MVC Core
So our development config file dev.js
looks like this:
// development config
const package = require('../../package.json')
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const commonConfig = require('./common')
module.exports = (webpackConfigEnv, argv) => {
return merge(commonConfig(argv), {
mode: 'development',
entry: [
'react-hot-loader/patch', // activate HMR for React
'webpack-dev-server/client?http://localhost:3030', //
'webpack/hot/only-dev-server', // bundle the client for hot reloading,
'./index.tsx', // the entry point of our app
],
devServer: {
port: 3030,
hot: true, // enable HMR on the server
historyApiFallback: true,
proxy: {
'/api/*': {
target: argv.env.mock ? '' : 'https://localhost:8800',
secure: false,
},
},
},
devtool: 'cheap-module-source-map',
plugins: [
new webpack.HotModuleReplacementPlugin(), // enable HMR globally
new webpack.DefinePlugin({
'process.env.appVersion': JSON.stringify(package.version),
'process.env.isMockMode': JSON.stringify(argv?.env?.mock),
'process.env.isDevelopment': true,
}),
],
})
}
However, authentication stopped working with this configuration. All API calls return 401 error.
I thought that CORS can solve the issue. However, authentication did not start to work after appying the following code:
public void ConfigureServices(IServiceCollection services)
{
// ... the other code is omitted for the brevity
services.AddCors();
// ... the other code is omitted for the brevity
services.AddAuthorization(options =>
{
options.AddPolicy("MyPolicy", policy =>
policy.Requirements.Add(new MyPolicyAuthorizationRequirement()));
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IAuthorizationHandler, MyPolicyAuthorizationRequirementHandler>();
services.AddScoped<IClaimsTransformation, WindowsAuthenticationClaimsTransformation>();
}
And Configure()
method:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<GlobalExceptionHandlerMiddleware>();
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseCookiePolicy();
app.UseStaticHttpContext();
app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod());
app.UseAuthentication();
app.UseAuthorization();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=FooAction}/{id?}");
});
}
If I build React application, then authentication works fine. Does anybody know what is wrong? Any help would be greatly appreciated.
CodePudding user response:
I've found a really great article about how we can send authorization headers through proxy.
So we need to use agent
and send https
headers through agent.
It is necessary to install the agentkeepalive
npm package:
npm install -D agentkeepalive
The complete proxy file looks like this:
// development config
const package = require('../../package.json')
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const commonConfig = require('./common')
const agent = require('agentkeepalive')
module.exports = (webpackConfigEnv, argv) => merge(commonConfig(argv), {
mode: 'development',
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:3030',
'webpack/hot/only-dev-server',
'./index.tsx', // the entry point of our app
],
devServer: {
port: 3030,
hot: true, // enable HMR on the server
historyApiFallback: true,
proxy: {
'/api/*': {
target: argv.env.mock ? '' : 'https://localhost:8800/',
secure: false,
changeOrigin: true,
agent: new agent.HttpsAgent({
maxSockets: 100,
keepAlive: true,
maxFreeSockets: 10,
keepAliveMsecs: 100000,
timeout: 6000000,
freeSocketTimeout: 90000, // free socket keepalive for 90 seconds
}),
onProxyRes: (proxyRes) => {
var key = 'www-authenticate'
proxyRes.headers[key] =
proxyRes.headers[key] && proxyRes.headers[key].split(',')
},
},
},
},
devtool: 'cheap-module-source-map',
plugins: [
new webpack.HotModuleReplacementPlugin(), // enable HMR globally
new webpack.DefinePlugin({
'process.env.appVersion': JSON.stringify(package.version),
'process.env.isMockMode': JSON.stringify(argv?.env?.mock),
'process.env.isDevelopment': true,
}),
],
})