7

我有一个node.js基于 Web 应用程序,需要https来自客户端的安全 ( ) 连接。我想要的是在某些路径上需要客户端证书身份验证,而在其他路径上则不需要。

举个例子。如果用户访问https://www.example.com/main,则服务器不需要客户端证书身份验证(因此浏览器不会询问任何内容)。但是如果用户导航到https://www.example.com/secure,则需要客户端证书身份验证(因此浏览器将弹出一个对话框以选择要使用的证书)。

我怎样才能做到这一点。如果我通过requestCert:true和 选项rejectUnauthorized:true,我可以强制客户端证书身份验证。https.createServer这种方法的问题是每个路径都需要客户端证书。

4

4 回答 4

1

我认为可以通过使用与 express 兼容的 Node.js 包 http-proxy-middleware(我们正在使用的 Web 服务器包)设置反向代理/API 网关来解决这个问题。

如 Node.js 包主页上的示例所示,可以这样完成: 1. 根据 http-proxy-middleware 使用的约定定义 UNAUTH 和 AUTH API 的重定向,并在下一步中使用。

  1. 在所需端口(例如 3000)上启动一个快速 HTTPS 网络服务器,并将 http-proxy-middleware 配置为充当反向代理/API 网关。无需在 https.createServer 选项中设置 requestCert 和 rejectUnauthorized。

  2. 在另一个端口(比如 3001)上启动一个快速 HTTPS 网络服务器来服务 UNAUTH API 请求。无需在 https.createServer 选项中设置 requestCert 和 rejectUnauthorized。

  3. 在另一个端口(比如 3002)上启动一个快速 HTTPS 网络服务器来服务 AUTH API 请求。将 requestCert:true 和 rejectUnauthorized:true 设置为 https.createServer 选项。

UNAUTH 请求将从 3000 到 3001 来回路由,AUTH 请求将从 3000 到 3002 来回路由。

于 2020-01-17T11:22:33.697 回答
1

您可以通过 TLS 重新协商来实现此目的,但不幸的是,TLS 1.3 不支持此功能,因此您必须禁用它:

https
    .createServer(
        {
            // configure key, cert, ca,
            secureOptions: require('constants').SSL_OP_NO_TLSv1_3,
        },
        function (req, res) {
            if (req.url.startsWith('/secure')) {
                req.socket.renegotiate(
                    {
                        requestCert: true,
                        rejectUnauthorized: true,
                    },
                    err => {
                        if (err) {
                            console.log('Renegotiation failed', err);
                            res.writeHead(500);
                            res.end('Internal Server Error');

                            return;
                        }

                        // handle secure content
                    },
                );
            } else {
                // handle main content
            }
        },
    )
    .listen(443);
于 2021-01-12T07:51:40.450 回答
1

我来到这里是因为我正在处理同样的问题,并将分享我正在采取的方法。对于要求用户使用有效证书进行身份验证的端点,我使用附加到需要证书的端点的自定义路径,并验证用户是否已使用证书进行身份验证,如果他们正在访问遵循该路径的任何端点(假定为 express 应用程序)。IE:

app.use('/api/cert', function(req, res, next){
    //validate that any token passed in the request was generated for a valid
    //cert login, otherwise reject request

    //pseudo-code
    if(isValidCertToken(req.authentication.token)) {
        next(); //this will pass it on to the correct endpoint in the /api/cert/[whatever] chain
    } else {
        req.status(401).send({error: 'invalid login, cert required'});
    }
});

这将要求您允许用户通过将requestCert标志设置为 true 来使用证书进行身份验证,但如果用户不希望使用“需要证书”端点,只要rejectUnauthorized设置为 false ,也将允许其他身份验证方法设置 https 连接时。

于 2015-10-07T03:40:22.627 回答
0

我不确定我是否完全理解你想要什么.. 但根据我的理解,如果你使用 express,你可以通过一个简单的中间件来管理这个东西。在那个中间件中,你可以跟踪来自 http 的任一请求或 https 通过这个

HTTPS 连接具有 req.connection.encrypted(包含有关 SSL 连接信息的对象)。HTTP 连接没有 req.connection.encrypted。

另外(来自文档):

使用 HTTPS 支持,使用 request.connection.verifyPeer() 和 request.connection.getPeerCertificate() 获取客户端的身份验证详细信息。

我希望这有帮助..

于 2013-01-23T09:09:47.953 回答