我正在尝试使用 node.js 构建 CAC 身份验证系统,但遇到了麻烦。我遵循了一些关于设置 https 服务器的教程,我可以让它正常工作;但是,每当我访问我的服务器时,使用下面的逻辑:
https://localhost:3000
系统提示我使用“/”路由处理程序发送的身份验证按钮登录;但是,它立即默认为 else 子句:
res.status(401)
.send(`Sorry, but you need to provide a client certificate to continue.`)
通常,当访问启用 cac 的站点时,会提示我选择一个智能卡证书,它允许我登录;但是,在这种情况下,我根本没有收到提示。
我在 SO 上发现了一个类似的问题,但无法从他们引用的文章中得到任何工作。他们提到我必须在 https 服务器上设置我的“ca”属性以允许相关 CAC 的特定 CA。我使用浏览器找到了我的 CAC 证书并导出了我的证书并将它们放入已批准的 CA 列表中,但我仍然没有得到任何提示。
我最初是req.connection.getPeerCertificate()
用来提示证书的;但是,我读到 req.connection 在我的 Node.JS (14.15.0) 版本中已被弃用,所以我也尝试过req.socket.getPeerCertificate()
. 无论哪种方式,服务器似乎都运行得很好,并且客户端或服务器端都没有错误(从服务器发送的 401 响应除外,因为它没有获得有效的证书)。任何和所有的见解将不胜感激。
const fs = require('fs')
const express = require('express')
const https = require('https')
// Https options
const options = {
// Path to private key (created by openssl in createSelfSignedCert.bat)
key: fs.readFileSync('server_key.pem')
// Path to public key
,cert: fs.readFileSync('server_cert.pem')
// Indicate that https server should request client certificates
,requestCert: true
// Manually handle bad requests (no certs)
,rejectUnauthorized: false
//List of accepted/valid CA certs - just our own for now
,ca: [
fs.readFileSync('server_cert.pem')
,fs.readFileSync('cac52.cer')
,fs.readFileSync('cac_export.p7b')
]
//,ca: .
}
// Use express for routing
const app = express()
// Unprotected public endpoint
app.get('/', (req, res) => {
res.send('<a href="login">Auth</a>')
})
// Protected endpoint
app.get('/login', (req, res) => {
// req.connection is deprecated, perhaps req.socket.getPeerCertificate()
const cert = req.connection.getPeerCertificate()
//const cert = req.socket.getPeerCertificate()
if (req.client.authorized) {
res.send(`Hello ${cert.subject.CN}, your certificate was issued by ${cert.issuer.CN}!`)
console.log(`${cert}`)
} else if (cert.subject) {
res.status(403)
.send(`Sorry ${cert.subject.CN}, certificates from ${cert.issuer.CN} are not welcome here.`)
console.log(`${cert}`)
} else {
res.status(401)
.send(`Sorry, but you need to provide a client certificate to continue.`)
}
})
// Create https server with options and app routes
https.createServer(options, app).listen(3000)