Home > Blockchain >  Authorization stopped working after using proxy
Authorization stopped working after using proxy

Time:05-30

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,
            }),
        ],
    })
  • Related