4

Description of what the bug is

We are developing at Windows 10. Our backend is ASP.NET Core 3.1 MVC

Windows Security dialog window pops up while I am developing an application through React. It is really annoying. We have to refresh page.

At first, this image is shown: enter image description here

Then the above dialog window is replaced by the following dialog window. It requires smart card credentials:

enter image description here

Settings of our application

package.json looks like this:

"devDependencies": {
    "@babel/cli": "7.14.3",
    "@babel/core": "7.14.3",
    "@babel/plugin-proposal-decorators": "7.14.2",
    "@babel/plugin-transform-runtime": "7.8.3",
    "@babel/preset-env": "7.14.4",
    "@babel/preset-react": "7.13.13",
    "@babel/preset-typescript": "7.13.0",
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^11.2.7",
    "@types/jest": "^27.5.1",
    "@types/node": "14.17.1",
    "@types/react": "17.0.8",
    "@types/react-dom": "17.0.5",
    "@types/webpack": "5.28.0",
    "@typescript-eslint/eslint-plugin": "4.25.0",
    "@typescript-eslint/parser": "4.25.0",
    "agentkeepalive": "4.2.1",
    "axios-mock-adapter": "^1.21.1",
    "babel-loader": "8.2.2",
    "css-loader": "5.2.6",
    "eslint": "7.27.0",
    "eslint-config-prettier": "8.3.0",
    "eslint-plugin-prettier": "3.4.0",
    "eslint-plugin-react": "7.23.2",
    "express": "4.17.1",
    "file-loader": "6.2.0",
    "html-webpack-plugin": "5.3.1",
    "husky": "6.0.0",
    "image-webpack-loader": "7.0.1",
    "jest": "^27.5.1",
    "lint-staged": "11.0.0",
    "prettier": "2.3.0",
    "react-hot-loader": "4.13.0",
    "rimraf": "3.0.2",
    "style-loader": "2.0.0",
    "ts-jest": "^27.1.3",
    "typescript": "4.3.2",
    "webpack": "5.38.1",
    "webpack-cli": "4.7.0",
    "webpack-dev-server": "3.11.2",
    "webpack-merge": "5.7.3"
},
"dependencies": {
    "@hot-loader/react-dom": "17.0.1",
    "@svgr/cli": "6.2.1",
    "@types/lodash": "4.14.170",
    "antd": "4.16.2",
    "axios": "^0.27.2",
    "classnames": "^2.3.1",
    "dotenv": "^16.0.1",
    "lodash": "4.17.21",
    "mobx": "6.3.2",
    "mobx-react": "7.2.0",
    "moment": "2.29.1",
    "process": "0.11.10",
    "react": "17.0.2",
    "react-base-table": "1.12.0",
    "react-dnd": "14.0.2",
    "react-dnd-html5-backend": "14.0.0",
    "react-dom": "17.0.2",
    "react-router-dom": "6.2.1",
    "react-sortable-hoc": "2.0.0",
    "ts-loader": "9.2.3"
}

In addition, we are using proxy. The settings are applied from this official React docs.

Moreover, we are using agentkeepalive.

Config of proxy file looks like this:

// development config
require('dotenv').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', // activate HMR for React
            '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 ? '' : process.env.API_URL,
                    secure: false,
                    changeOrigin: true,
                    agent: new agent({
                        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,
            }),
        ],
    })

The current behavior

Windows Security dialog window sometimes pops up while I am developing an application through React. It is really annoying. We have to refresh page

The expected behavior

Windows Security dialog window sometimes DOES NOT POP UP while we are developing an application through React.

What we tried

We tried to set this option of axios, nevertheless the "Sign in" still pops up

axios.defaults.withCredentials = true;

UPDATE:

This is one of the URL that can return the 401 response with www-authenticate header-key:

 http://localhost:3030/api/notifications

Moreover, sometimes other methods can return 401 response. It is not always the same method return 401 response.

enter image description here

Learner
  • 417
  • 6
  • 24
  • 3
    Please share the Network Analysis from the Dev Tools of your browser. Which URL returns the `401` response with `www-authenticate` header-key? – Markus Aug 22 '22 at 16:49
  • 1
    [Please check this answer.](https://stackoverflow.com/questions/47811015/webpack-dev-server-hot-reloading-proxy-iis-express-with-windows-authentication) – Jason Pan Aug 23 '22 at 12:13
  • So the authentication request is made by your `proxied` ASP.NET-`api`. It asks for `Negotiate` or `NTLM`. Can you share some further information about the authentication configuration of your ASP.NET app? Are you using IIS? Are you using Kerberos? – Markus Aug 23 '22 at 13:15
  • @Markus yeah, we are using IIS. In addition, it happens when we run Visual Studio locally. – Learner Aug 24 '22 at 06:52
  • @JasonPan thank for you comment, howeverI have the same configuration of `agentkeepalive` – Learner Aug 24 '22 at 06:56
  • Are you using Kerberos on your IIS for authentication? – Markus Aug 24 '22 at 07:26
  • @Markus I am sorry I do not know. I am running my application locally - I mean I run Visual Studio and then run React application. So it looks like we are using IIS Express. How can I know whether I use Kerberos? – Learner Aug 24 '22 at 07:37
  • Try to switch off any authentication: https://stackoverflow.com/a/7168308/18667225 – Markus Aug 24 '22 at 08:47
  • @Markus sorry, however, I cannot do it. I should use authentication. – Learner Aug 24 '22 at 09:38

1 Answers1

0

Your api server based on IIS expects a valid authentication. It asks for Negotiate (see here), which is essentially Kerberos. Your browser accepts this but the negotiation fails, because you are trying to access the api url with a different base url than configured as SPN in IIS and because you are not using https.

There are at least two possibilties you can try:

  1. Best for development is to mock all your calls to the api server. So no IIS-Server is called at all and no authentication is needed.
  2. Try to switch off Negotiate in your development IIS just using NTLM.
Markus
  • 5,976
  • 5
  • 6
  • 21