Files
SGU-CredentialProvider/scripts/Deploy-AuthBroker.ps1
T

178 lines
7.9 KiB
PowerShell

[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[string]$PublishPath,
[Parameter(Mandatory)]
[string]$ServerCertificateSubject,
[Parameter(Mandatory)]
[ValidatePattern('^[0-9A-Fa-f ]{40,59}$')]
[string[]]$AllowedClientThumbprints,
[string]$NtlmEndpoint = 'https://sgu.ulsa.edu.mx/',
[string[]]$AllowedNtlmRedirectHosts = @('sgu.ulsa.edu.mx'),
[ValidatePattern('^/')]
[string]$AdministrativeProfilePath = '/psulsa/gadmon/capitalhumano/controlincidencias/incidencias.aspx',
[ValidatePattern('^/')]
[string]$MenuProfilePath = '/psulsa/menu.aspx',
[ValidateRange(32768, 2097152)]
[int]$MaxProfileBytes = 524288,
[string]$LdapHost = 'localhost',
[string]$BaseDn = 'DC=lci,DC=lasalle,DC=mx',
[string]$DomainNetbios = 'LCI',
[string]$UpnSuffix = 'lci.lasalle.mx',
[switch]$CreateMissingOus,
[switch]$DisableCertificateRevocationCheckForLab
)
$ErrorActionPreference = 'Stop'
$serviceName = 'SGUAuthBroker'
$installPath = Join-Path $env:ProgramFiles 'SGU\AuthBroker'
$normalizedClientThumbprints = @($AllowedClientThumbprints | ForEach-Object { $_ -replace ' ', '' })
if ($normalizedClientThumbprints.Where({ $_.Length -ne 40 }).Count -gt 0) {
throw 'Client certificate thumbprints must contain exactly 40 hexadecimal characters.'
}
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw 'Run this script from an elevated PowerShell session on the broker server.'
}
$serverCertificate = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*$ServerCertificateSubject*" -and $_.HasPrivateKey } |
Sort-Object NotAfter -Descending |
Select-Object -First 1
if (-not $serverCertificate) {
throw 'The HTTPS server certificate with private key was not found in LocalMachine\My.'
}
if (-not $serverCertificate.Verify()) {
throw 'The HTTPS server certificate chain is not trusted or is outside its validity period. Import the issuing CA chain; for a self-signed lab certificate, trust its public .cer in LocalMachine\Root.'
}
if ($CreateMissingOus) {
Import-Module ActiveDirectory -ErrorAction Stop
$usersOuName = 'Usuarios-SGU'
$usersOuDn = "OU=$usersOuName,$BaseDn"
if (-not (Get-ADOrganizationalUnit -LDAPFilter "(ou=$usersOuName)" -SearchBase $BaseDn -SearchScope OneLevel -Server $LdapHost -ErrorAction SilentlyContinue)) {
New-ADOrganizationalUnit -Name $usersOuName -Path $BaseDn -ProtectedFromAccidentalDeletion $true -Server $LdapHost | Out-Null
}
foreach ($ouName in @('Docentes', 'Alumnos', 'Administrativos')) {
$targetOu = Get-ADOrganizationalUnit -LDAPFilter "(ou=$ouName)" -SearchBase $usersOuDn -SearchScope OneLevel -Properties ProtectedFromAccidentalDeletion -Server $LdapHost -ErrorAction SilentlyContinue
if ($targetOu) {
if (-not $targetOu.ProtectedFromAccidentalDeletion) {
$targetOuDn = [string]$targetOu.DistinguishedName
Set-ADOrganizationalUnit -Identity $targetOuDn -ProtectedFromAccidentalDeletion $true -Server $LdapHost -Confirm:$false
}
continue
}
$legacyOu = Get-ADOrganizationalUnit -LDAPFilter "(ou=$ouName)" -SearchBase $BaseDn -SearchScope OneLevel -Properties ProtectedFromAccidentalDeletion -Server $LdapHost -ErrorAction SilentlyContinue
if ($legacyOu) {
$legacyOuDn = [string]$legacyOu.DistinguishedName
try {
if ($legacyOu.ProtectedFromAccidentalDeletion) {
Set-ADOrganizationalUnit -Identity $legacyOuDn -ProtectedFromAccidentalDeletion $false -Server $LdapHost -Confirm:$false
Start-Sleep -Seconds 1
}
Move-ADObject -Identity $legacyOuDn -TargetPath $usersOuDn -Server $LdapHost -Confirm:$false -ErrorAction Stop
}
finally {
$currentOu = Get-ADOrganizationalUnit -LDAPFilter "(ou=$ouName)" -SearchBase $usersOuDn -SearchScope OneLevel -Properties ProtectedFromAccidentalDeletion -Server $LdapHost -ErrorAction SilentlyContinue
if (-not $currentOu) {
$currentOu = Get-ADOrganizationalUnit -LDAPFilter "(ou=$ouName)" -SearchBase $BaseDn -SearchScope OneLevel -Properties ProtectedFromAccidentalDeletion -Server $LdapHost -ErrorAction SilentlyContinue
}
if ($currentOu) {
$currentOuDn = [string]$currentOu.DistinguishedName
Set-ADOrganizationalUnit -Identity $currentOuDn -ProtectedFromAccidentalDeletion $true -Server $LdapHost -Confirm:$false
}
}
}
else {
New-ADOrganizationalUnit -Name $ouName -Path $usersOuDn -ProtectedFromAccidentalDeletion $true -Server $LdapHost | Out-Null
}
}
}
foreach ($file in @('SGU.AuthBroker.exe', 'SGU.AuthBroker.dll', 'appsettings.json')) {
if (-not (Test-Path -LiteralPath (Join-Path $PublishPath $file))) {
throw "PublishPath is missing $file."
}
}
$productionSettings = @{
Kestrel = @{
Endpoints = @{
Https = @{
Url = 'https://0.0.0.0:8443'
Certificate = @{
Subject = $ServerCertificateSubject
Store = 'My'
Location = 'LocalMachine'
AllowInvalid = $false
}
}
}
}
Broker = @{
Tls = @{
AllowedClientThumbprints = $normalizedClientThumbprints
CheckCertificateRevocation = -not $DisableCertificateRevocationCheckForLab
}
Ntlm = @{
Endpoint = $NtlmEndpoint
Domain = ''
TimeoutSeconds = 15
MaxRedirects = 5
AdministrativeProfilePath = $AdministrativeProfilePath
MenuProfilePath = $MenuProfilePath
MaxProfileBytes = $MaxProfileBytes
AllowedRedirectHosts = $AllowedNtlmRedirectHosts
}
Directory = @{
LdapHost = $LdapHost
BaseDn = $BaseDn
DomainNetbios = $DomainNetbios
UpnSuffix = $UpnSuffix
ProfessorOuDn = "OU=Docentes,OU=Usuarios-SGU,$BaseDn"
StudentOuDn = "OU=Alumnos,OU=Usuarios-SGU,$BaseDn"
AdministrativeOuDn = "OU=Administrativos,OU=Usuarios-SGU,$BaseDn"
CreateMissingOus = [bool]$CreateMissingOus
}
}
}
if ($PSCmdlet.ShouldProcess($installPath, 'Install the SGU Authentication Broker Windows service')) {
if (Get-Service -Name $serviceName -ErrorAction SilentlyContinue) {
Stop-Service -Name $serviceName -Force
}
New-Item -ItemType Directory -Path $installPath -Force | Out-Null
Copy-Item -Path (Join-Path $PublishPath '*') -Destination $installPath -Recurse -Force
$settingsJson = $productionSettings | ConvertTo-Json -Depth 8
$utf8WithoutBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText(
(Join-Path $installPath 'appsettings.Production.json'),
$settingsJson,
$utf8WithoutBom)
if (-not (Get-Service -Name $serviceName -ErrorAction SilentlyContinue)) {
New-Service -Name $serviceName `
-DisplayName 'SGU Authentication Broker' `
-Description 'Validates SGU NTLM credentials and synchronizes Active Directory accounts.' `
-BinaryPathName ('"{0}"' -f (Join-Path $installPath 'SGU.AuthBroker.exe')) `
-StartupType Automatic
}
if (-not (Get-NetFirewallRule -DisplayName 'SGU Authentication Broker (mTLS)' -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName 'SGU Authentication Broker (mTLS)' `
-Direction Inbound -Action Allow -Protocol TCP -LocalPort 8443 -Profile Domain | Out-Null
}
Start-Service -Name $serviceName
}
Get-Service -Name $serviceName | Select-Object Name, Status, StartType