使用代理后授权停止工作

Authorization stopped working after using proxy

我们正在使用 ASP.NET Core 3.1 MVC 和 React 17.0.2。此外,Windows 使用身份验证。

By reading this documentation,我们添加了一个代理文件来代理 API 对 ASP.NET MVC Core

的调用

所以我们的开发配置文件 dev.js 看起来像这样:

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

但是,身份验证已停止使用此配置。所有 API 调用 return 401 错误。

我以为CORS可以解决问题。但是,在应用以下代码后,身份验证没有开始工作:

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>();
}

Configure()方法:

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?}");
    });
}

如果我构建 React 应用程序,则身份验证工作正常。 有人知道哪里出了问题吗?任何帮助将不胜感激。

我发现 really great article 关于如何通过代理发送授权 headers。

所以我们需要使用agent并通过代理发送httpsheaders

需要安装agentkeepalive npm包:

npm install -D agentkeepalive

完整的代理文件如下所示:

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