Skip To Content

创建域证书

ArcGIS Enterprise 使用 HTTPS,这需要为门户配置证书。 从 2017 年开始,Chrome Internet 浏览器仅信任具有主题备选名称 (SAN) 参数的域证书。 此参数不能由 IIS 管理器应用程序单独配置,这意味着从该工作流产生的证书不受 Chrome 的信任。

在大多数情况下,您的 IT 管理员将为您提供必要的域证书。 以下脚本将创建一个包含 SAN 的证书,并以可导入门户的格式将其从 IIS 管理器中导出。

保存并运行证书脚本

要创建域证书,您的域必须具有证书颁发机构,并且您的计算机必须已安装 IIS 管理器。 建议在 Windows PowerShell ISE 环境下进行此工作流,因为该环境可提供脚本窗口和命令提示符窗口。

如果计算机上存在主机名证书,则脚本将提示您是否要覆盖现有证书。

  1. 在计算机上使用以管理员身份运行选项打开 Windows PowerShell ISE 应用程序,并创建脚本。
  2. 将以下文本复制到应用程序的脚本窗口中。
  3. 将脚本另存为 .ps1 文件,例如 certificateScript.ps1
  4. 在 ISE 应用程序的命令提示符面板中,将目录更改为保存脚本的位置,然后运行 .\certificateScript.ps1 脚本。

将在 PowerShell 中运行的证书脚本

function New-CertificateRequest {
    param ( [string]$hostname )
 
    $CATemplate = "WebServer"
    $CertificateINI = "cert.ini"
    $CertificateREQ = "cert.req"
    $CertificateRSP = "cert.rsp"
    $CertificateCER = "cert.cer"
    $Subject = 'Subject="CN=' + $hostname + '"'
    $FriendlyName = 'FriendlyName=' + $hostname
    $SAN = '_continue_ = "dns=' + $hostname + '&"'
 
    ### INI file generation
    new-item -type file $CertificateINI -force
    add-content $CertificateINI '[Version]'
    add-content $CertificateINI 'Signature="$Windows NT$"'
    add-content $CertificateINI ''
    add-content $CertificateINI '[NewRequest]'
    add-content $CertificateINI $Subject
    add-content $CertificateINI 'Exportable=TRUE'
    add-content $CertificateINI 'KeyLength=2048'
    add-content $CertificateINI 'KeySpec=1'
    add-content $CertificateINI 'KeyUsage=0xA0'
    add-content $CertificateINI 'MachineKeySet=True'
    add-content $CertificateINI 'ProviderName="Microsoft RSA SChannel Cryptographic Provider"'
    add-content $CertificateINI 'ProviderType=12'
    add-content $CertificateINI 'SMIME=FALSE'
    add-content $CertificateINI 'RequestType=PKCS10'
    add-content $CertificateINI $FriendlyName
    add-content $CertificateINI '[Strings]'
    add-content $CertificateINI 'szOID_ENHANCED_KEY_USAGE = "2.5.29.37"'
    add-content $CertificateINI 'szOID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"'
    add-content $CertificateINI 'szOID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2"'
    add-content $CertificateINI 'szOID_SUBJECT_ALT_NAME2 = "2.5.29.17"'
    add-content $CertificateINI '[Extensions]'
    add-content $CertificateINI '2.5.29.17 = "{text}"'
    add-content $CertificateINI $SAN

 
    ### Certificate request generation
    if (test-path $CertificateREQ) {del $CertificateREQ}
    certreq -new $CertificateINI $CertificateREQ
 
    ### Online certificate request and import
    if ($OnlineCA) {
        if (test-path $CertificateCER) {del $CertificateCER}
        if (test-path $CertificateRSP) {del $CertificateRSP}
        certreq -submit -attrib "CertificateTemplate:$CATemplate" -config $OnlineCA $CertificateREQ $CertificateCER
        certreq -accept $CertificateCER
    }
    
    ### Delete certificate request files
    if (test-path $CertificateINI) {del $CertificateINI}
    if (test-path $CertificateREQ) {del $CertificateREQ}
    if (test-path $CertificateRSP) {del $CertificateRSP}
    if (test-path $CertificateCER) {del $CertificateCER}
}

## Main
if ($args.length -ne 0) {$hostname = $args[0]}
else {$hostname = "$env:computername.$env:userdnsdomain".ToLower()}

# Check if a CA exists in the domain and if IIS is installed
if (@(certutil -dump | select-string "Config:")) {
    $OnlineCA = (certutil -dump | select-string "Config:")[-1].Line.replace("``",'"').replace("'",'"').split('"')[1]
} else {
    Write-Host "Unable to determine certificate authority (CA) for this domain"
    Exit
}
if (-not @(Get-Service W3SVC -ErrorAction Ignore)) {
    Write-Host "IIS is not installed on this machine"
    Exit
}

# Check if a certificate already exists and prompt user to overwrite
if (@(Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" }).count -ne 0) {
    Write-Host "A certificate for $hostname already exists"
    $reply = Read-Host -Prompt "Overwrite existing certificate? (y/n)"
    if ( $reply -notmatch "[yY]" ) { Exit }
    Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Remove-Item
}
New-CertificateRequest -hostname $hostname > $null
Write-Host "`nCreated a new certificate for $hostname"

# Create https binding if necessary and add new cert to https binding
import-module WebAdministration
if (@(Get-WebBinding -name "Default Web Site" | Where-Object {$_.protocol -eq "https"}).count -eq 0) {
    New-WebBinding -name "Default Web Site" -Protocol https -Port 443
    Write-Host 'Created https binding for "Default Web Site"'
}
if (@(netsh http show sslcert ipport="0.0.0.0:443" | select-string -pattern "IP:port").count -ne 0) {
    netsh http delete sslcert ipport="0.0.0.0:443" > $null
}
$cert = (Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Select-Object -First 1).Thumbprint
$guid = [guid]::NewGuid().ToString("B")
netsh http add sslcert ipport="0.0.0.0:443" certhash=$cert certstorename=MY appid="$guid" > $null
Write-Host "Updated https binding to use this certificate"

# Export certificate to .pfx (Windows 2012 and higher)
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
if ([Environment]::OSVersion.Version -ge (new-object 'Version' 6,2)) {
    $pfxname = $hostname.Split(".")[0]
    if ($pfxname -eq '*') {$pfxname = "wildcard"}
    $pfxname = $pfxname + ".pfx"
    Remove-Item $scriptPath\$pfxname -ErrorAction Ignore
    $pfxpwd = ConvertTo-SecureString -String "certificate" -Force -AsPlainText
    $cert = (Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Select-Object -First 1).Thumbprint
    Get-ChildItem -Path cert:\localMachine\My\$cert | Export-PfxCertificate -FilePath $scriptPath\$pfxname -Password $pfxpwd -ChainOption EndEntityCertOnly > $null
    Write-Host "Exported certificate in PFX format with password 'certificate' to"
    Write-Host "    $scriptPath\$pfxname"
}

# Export domain CA root certificate to domainRoot.cer
Remove-Item $scriptPath\domainRoot.cer -ErrorAction Ignore
certutil -config $OnlineCA '-ca.cert' $scriptPath\domainRoot.cer > $null
Write-Host "Exported domain root certificate to"
Write-Host "    $scriptPath\domainRoot.cer"

将新证书导入到现有部署中

如果已建立 ArcGIS Enterprise 部署,请按照以下步骤将新证书导入您的 ArcGIS Enterprise 门户和托管服务器中,并使其成为这两个组件的默认 Web 证书。

这些步骤概述了如何导入通过脚本导出的两个证书文件:作为 .cer 文件的域根证书和作为 .pfx 文件的服务器证书。 应将这两个文件置于保存脚本的相同文件夹中;执行脚本时,在命令提示符输出中也将提供这两个文件位置。

  1. https://sample.domain.com:7443/arcgis/portaladmin 登录到您的 ArcGIS Portal Administrator Directory。
  2. 请浏览至安全性 > SSL 证书并单击导入根或中间证书
  3. 提供证书别名以及到通过上述脚本导出的 domainRoot.cer 文件的文件路径。 选择导入后不重启门户选项(步骤 7 中的操作将重新启动门户),然后单击导入
  4. 浏览回到 SSL 证书并单击导入现有的服务器证书
  5. 键入 certificate 作为证书密码,并键入与您为根证书提供的别名不同的证书别名,然后在您的计算机上浏览至 .pfx 文件。 单击导入
  6. 返回到 SSL 证书页面并单击更新
  7. 使用在步骤 5 中导入的 .pfx 证书的别名替换 Web 服务器 SSL 证书的值。 单击更新

    门户将重新启动,这可能需要几分钟时间。

  8. https://sample.domain.com:6443/arcgis/admin 登录到您的 ArcGIS Server Administrator Directory。
  9. 浏览至计算机 > <计算机名称> > sslcertificates 并单击 importRootOrIntermediate
  10. 按照步骤 3 提供别名并浏览到 domainRoot.cer 文件的位置。 单击导入
  11. 浏览回计算机页面并单击 importExistingServerCertificate
  12. 键入证书密码,并键入 .pfx 证书在您计算机上的位置。 单击提交
  13. 返回计算机页面并单击编辑
  14. 使用新域证书的别名替换 Web 服务器 SSL 证书的值。 单击保存编辑

    服务器计算机将重新启动,这可能需要几分钟时间。

ArcGIS Enterprise 门户和托管服务器的新证书现在将受到所有 web 浏览器的信任。