我有一个基于node.js
的网络应用,需要来自客户端的安全(https
)连接。我想要的是在某些路径上需要客户端证书身份验证,而在其他路径上则不需要。
所以举个例子。如果用户转到https://www.example.com/main,则服务器不需要客户端证书身份验证(因此浏览器不会询问任何内容)。但是,如果用户导航到https://www.example.com/secure,则需要客户端证书身份验证(因此浏览器将弹出一个对话框,用于选择要使用的证书)。
我怎样才能实现这一目标。如果我将requestCert:true
和rejectUnauthorized:true
传递给https.createServer
选项,我可以强制进行客户端证书身份验证。这种方法的问题是每条路径都需要客户端证书。
答案 0 :(得分:1)
我来到这里是因为我正在研究同样的问题,并将分享我所采取的方法。对于要求用户使用有效证书进行身份验证的端点,我使用附加到需要证书的端点的自定义路径,并验证用户是否使用证书进行身份验证(如果他们正在访问遵循该路径的任何端点)(假设使用Express应用程序)。即:
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来使用证书进行身份验证,但如果用户不希望使用"证书,还将允许其他身份验证方法所需"端点,只要在设置https connecton时将rejectUnauthorized
设置为false。
答案 1 :(得分:0)
我不确定我是否完全理解你想要的东西..但根据我的理解,如果你使用快递,你可以通过一个简单的中间件管理这个东西..在那个中间件你可以跟踪任何一个请求是来自http或https来自
HTTPS连接具有req.connection.encrypted(包含SSL连接信息的对象)。 HTTP连接没有req.connection.encrypted。
另外(来自文档):
使用HTTPS支持,使用request.connection.verifyPeer()和request.connection.getPeerCertificate()来获取客户端的身份验证详细信息。
我希望这有帮助..
答案 2 :(得分:0)
您可以通过 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);