Add SGU credential provider and authentication broker
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
# Architecture
|
||||
|
||||
## Online authentication
|
||||
|
||||
```text
|
||||
LogonUI
|
||||
-> SGU Credential Provider (SecureString)
|
||||
-> HTTPS 1.1 + client certificate
|
||||
-> SGU Auth Broker
|
||||
-> SGU IIS NTLM endpoint (original password)
|
||||
-> Active Directory (same original password)
|
||||
<- domain + canonical username; never a password
|
||||
-> Windows credential serialization (original SecureString)
|
||||
-> LSA / Kerberos / cached domain logon
|
||||
```
|
||||
|
||||
The broker performs the NTLM exchange and AD update before returning `200 OK`.
|
||||
It follows only HTTPS redirects whose host appears in `AllowedRedirectHosts`,
|
||||
which prevents credential forwarding to an unexpected redirect target. HTTP/1.1
|
||||
is forced because NTLM authentication is connection-bound.
|
||||
|
||||
## Offline authentication
|
||||
|
||||
```text
|
||||
Broker timeout, TLS failure, 429, or 5xx
|
||||
-> provider preserves the entered username/password
|
||||
-> Windows LSA validates against AD or its cached domain verifier
|
||||
-> only the last AD password succeeds
|
||||
```
|
||||
|
||||
An explicit `400` or `401` from the broker is different: the provider displays
|
||||
an error and does not serialize the rejected credential.
|
||||
|
||||
## Account synchronization
|
||||
|
||||
The broker normalizes the username to uppercase and accepts exactly two letters
|
||||
plus six digits. It searches `BaseDn` by `sAMAccountName`, creates the user when
|
||||
absent, moves it to the mapped OU when required, sets `userPrincipalName`, and
|
||||
passes the submitted password directly to ADSI `SetPassword`.
|
||||
|
||||
The managed hierarchy is rooted at `OU=Usuarios-SGU`: `Docentes`, `Alumnos`,
|
||||
and `Administrativos` are direct child OUs beneath it.
|
||||
|
||||
Per-user synchronization is serialized inside the broker to prevent concurrent
|
||||
create/reset races. Production deployments should run the broker as a gMSA with
|
||||
delegated create-user, move-user, write-property, enable-account, and reset-password
|
||||
rights limited to `Usuarios-SGU` and its three managed child OUs. The lab can run it on the domain
|
||||
controller as LocalSystem.
|
||||
@@ -0,0 +1,144 @@
|
||||
# Hyper-V lab runbook
|
||||
|
||||
Validated lab inventory:
|
||||
|
||||
- Domain controller/broker: Windows Server 2025 Standard,
|
||||
`WIN-1AIQMMA1EPR.lci.lasalle.mx`, `192.168.50.10`.
|
||||
- Client: Windows 10 Pro 22H2,
|
||||
`DESKTOP-U1I3BNN.lci.lasalle.mx`, `192.168.50.20`.
|
||||
- Domain: `lci.lasalle.mx` / `LCI`.
|
||||
- Private switch: `Laboratorio AD`.
|
||||
|
||||
Run guest commands from an elevated PowerShell console inside each VM. Do not
|
||||
put an institutional password on a command line or in a script file.
|
||||
|
||||
## 1. Build on the Windows 11 host
|
||||
|
||||
```powershell
|
||||
Set-Location C:\Users\alex\Documents\projects\SGU-CredentialProvider
|
||||
dotnet restore .\SGU-CredentialProvider.sln
|
||||
dotnet build .\SGU-CredentialProvider.sln -c Release --no-restore
|
||||
dotnet test .\SGU-CredentialProvider.sln -c Release --no-build --no-restore
|
||||
.\scripts\Publish-Lab.ps1
|
||||
```
|
||||
|
||||
Copy `artifacts\broker` and the deployment/certificate scripts to Windows Server.
|
||||
Copy `artifacts\credential-provider` and the installation/certificate scripts to
|
||||
Windows 10. Hyper-V Guest Service Interface or an ISO can be used because the
|
||||
lab switch is private.
|
||||
|
||||
## 2. Create non-exportable lab certificates
|
||||
|
||||
On Windows Server:
|
||||
|
||||
```powershell
|
||||
.\New-LabCertificate.ps1 -Role BrokerServer
|
||||
```
|
||||
|
||||
On Windows 10:
|
||||
|
||||
```powershell
|
||||
.\New-LabCertificate.ps1 -Role CredentialProviderClient
|
||||
```
|
||||
|
||||
Exchange only the two generated `.cer` public files. Never move a private key.
|
||||
The helper also trusts each self-signed public certificate on the machine where
|
||||
it was created. This is required because the provider deliberately refuses
|
||||
client certificates whose chain is not locally valid.
|
||||
On Windows Server, import the client public certificate; on Windows 10, import
|
||||
the server public certificate:
|
||||
|
||||
```powershell
|
||||
.\Import-LabPeerCertificate.ps1 -CertificatePath .\peer.cer
|
||||
```
|
||||
|
||||
Record both reported thumbprints. For a production CA, import the issuing CA
|
||||
chain instead and leave revocation checking enabled.
|
||||
|
||||
## 3. DNS and broker
|
||||
|
||||
The broker VM needs an internet-capable adapter in addition to the private lab
|
||||
adapter. On Windows Server, create the broker DNS record and set explicit lab
|
||||
forwarders so public SGU resolution survives a reboot. Use the Hyper-V Default
|
||||
Switch gateway shown by `Get-NetIPConfiguration` as the first forwarder; the
|
||||
public resolvers below are lab fallbacks. Production must use organization-
|
||||
approved DNS forwarders.
|
||||
|
||||
```powershell
|
||||
Get-NetIPConfiguration
|
||||
.\Set-LabBrokerDns.ps1 `
|
||||
-ExternalForwarders 172.30.32.1,1.1.1.1,8.8.8.8
|
||||
Resolve-DnsName sgu-auth.lci.lasalle.mx
|
||||
Resolve-DnsName sgu.ulsa.edu.mx
|
||||
```
|
||||
|
||||
Deploy the broker, supplying the server certificate subject and client
|
||||
certificate thumbprint:
|
||||
|
||||
```powershell
|
||||
.\Deploy-AuthBroker.ps1 `
|
||||
-PublishPath C:\Deploy\broker `
|
||||
-ServerCertificateSubject sgu-auth.lci.lasalle.mx `
|
||||
-AllowedClientThumbprints CLIENT_CERT_THUMBPRINT `
|
||||
-CreateMissingOus `
|
||||
-DisableCertificateRevocationCheckForLab
|
||||
```
|
||||
|
||||
Verify the service and managed OUs:
|
||||
|
||||
```powershell
|
||||
Get-Service SGUAuthBroker
|
||||
Get-ADOrganizationalUnit -Filter * -SearchBase 'OU=Usuarios-SGU,DC=lci,DC=lasalle,DC=mx'
|
||||
```
|
||||
|
||||
## 4. Broker preflight from Windows 10
|
||||
|
||||
Use the interactive credential prompt so the password is not placed in shell
|
||||
history:
|
||||
|
||||
```powershell
|
||||
.\Test-Broker.ps1 `
|
||||
-BrokerEndpoint https://sgu-auth.lci.lasalle.mx:8443/v1/authenticate `
|
||||
-ClientCertificateThumbprint CLIENT_CERT_THUMBPRINT
|
||||
```
|
||||
|
||||
Verify the returned domain/username, then confirm the user exists in the mapped
|
||||
OU on Windows Server. Use separate authorized test accounts for `DO`, `AL`, and
|
||||
`AD` when available.
|
||||
|
||||
## 5. Install the Credential Provider
|
||||
|
||||
On Windows 10:
|
||||
|
||||
```powershell
|
||||
.\Install-CredentialProvider.ps1 `
|
||||
-PublishPath C:\Deploy\credential-provider `
|
||||
-BrokerEndpoint https://sgu-auth.lci.lasalle.mx:8443/v1/authenticate `
|
||||
-ClientCertificateThumbprint CLIENT_CERT_THUMBPRINT `
|
||||
-ServerCertificateThumbprint SERVER_CERT_THUMBPRINT `
|
||||
-InstallDotNetRuntime `
|
||||
-DotNetRuntimeInstallerPath C:\SGUDeploy\prerequisites\dotnet-runtime-10.0.11-win-x64.exe
|
||||
```
|
||||
|
||||
Use Lithnet's `Invoke-CredUI` test utility when available, or lock the VM and
|
||||
select **Acceso institucional SGU** under sign-in options. Keep the built-in
|
||||
Windows password tile visible.
|
||||
|
||||
## 6. Required end-to-end cases
|
||||
|
||||
1. Online valid `DO`, `AL`, and `AD` logons; verify each OU.
|
||||
2. Explicit bad institutional password; verify rejection and no AD password reset.
|
||||
3. Change the institutional password, log on online once, and verify the new value
|
||||
becomes the AD password.
|
||||
4. Stop `SGUAuthBroker`; verify the last synchronized AD password still logs on
|
||||
through Windows cached/domain validation.
|
||||
5. While the broker is stopped, verify a different password fails.
|
||||
6. Start `SGUAuthBroker`; verify online synchronization recovers.
|
||||
7. Verify the Microsoft password Credential Provider still works throughout.
|
||||
|
||||
## Rollback
|
||||
|
||||
Run `Uninstall-CredentialProvider.ps1` in an elevated Windows 10 session. By
|
||||
default it removes only registration; add `-RemoveFiles` after reboot when the
|
||||
COM DLL is no longer loaded. Stop/remove the `SGUAuthBroker` service and firewall
|
||||
rule separately only after clients have been rolled back.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Security model
|
||||
|
||||
## Password handling
|
||||
|
||||
- The Credential Provider receives the password in Lithnet's secure password
|
||||
control and keeps that `SecureString` for Windows serialization.
|
||||
- A temporary managed string is unavoidable when creating the HTTPS JSON body.
|
||||
The unmanaged conversion buffer is zeroed immediately with
|
||||
`Marshal.ZeroFreeGlobalAllocUnicode`; managed references are released as soon
|
||||
as each request completes.
|
||||
- The broker uses the exact received value for both NTLM and AD `SetPassword`.
|
||||
- There is no HMAC password, pepper, local password cache, Supabase password, or
|
||||
other derived credential in this Windows path.
|
||||
- Neither application logs request bodies or passwords. Deployment configuration
|
||||
contains certificate thumbprints, not passwords or private keys.
|
||||
|
||||
## Transport
|
||||
|
||||
- HTTPS is mandatory on both links.
|
||||
- Credential Provider to broker uses mutual TLS. The provider requires normal
|
||||
Windows certificate validation and pins the configured server certificate.
|
||||
- The broker requires a trusted client certificate and an explicit allow-listed
|
||||
thumbprint.
|
||||
- Client private keys are non-exportable and reside in `LocalMachine\My`.
|
||||
- The NTLM validator rejects non-HTTPS redirects, URI user information, and hosts
|
||||
outside its explicit redirect allow-list.
|
||||
|
||||
Lab self-signed certificates are appropriate only for the isolated VM network.
|
||||
Use an enterprise CA with revocation checking in production.
|
||||
|
||||
## Recovery and availability
|
||||
|
||||
The provider distinguishes an authoritative rejection from unavailable
|
||||
infrastructure:
|
||||
|
||||
- `400`/`401`: fail closed and show an error.
|
||||
- timeout, TLS/connectivity error, `429`, or `5xx`: submit the unchanged credential
|
||||
to Windows. Windows must still validate it against AD or the cached domain
|
||||
verifier, so this does not grant access without the last synchronized password.
|
||||
|
||||
The installer never registers a Credential Provider filter and never disables
|
||||
Microsoft's password, PIN, smart-card, or Windows Hello providers.
|
||||
|
||||
## Operational controls
|
||||
|
||||
- Limit the firewall rule to the Domain profile and required client networks.
|
||||
- Delegate the broker service account only to `OU=Usuarios-SGU` and its managed child OUs.
|
||||
- Keep broker/client certificates short lived and rotate their allow-list entries.
|
||||
- Monitor service availability and AD provisioning events without enabling HTTP
|
||||
body logging.
|
||||
- Test uninstall and the built-in password provider before broad rollout.
|
||||
- Do not test a new build first on a physical production endpoint; use a VM with
|
||||
a recent checkpoint and a known local administrator recovery account.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Toolchain
|
||||
|
||||
## Development host
|
||||
|
||||
- Windows 11 with Hyper-V.
|
||||
- Visual Studio 2026 with `.vsconfig` workloads.
|
||||
- .NET SDK 10.0.400 or a compatible later 10.0 feature band.
|
||||
- Windows 11 SDK 10.0.28000.
|
||||
- MSVC x64/x86 tools, CMake, Ninja, WinDbg, Git, and PowerShell 7/Windows PowerShell.
|
||||
|
||||
The SGU additions are C#, but the repository keeps the upstream native/COM
|
||||
interop source and benefits from the full Windows desktop toolchain.
|
||||
|
||||
## Windows Server target
|
||||
|
||||
The broker is published self-contained for `win-x64`. It requires:
|
||||
|
||||
- Windows Server 2025 or supported Windows Server with AD management APIs.
|
||||
- An HTTPS server certificate in `LocalMachine\My`.
|
||||
- Trusted and allow-listed client certificates.
|
||||
- Delegated AD rights for `OU=Usuarios-SGU` and its managed child OUs.
|
||||
- Network access to the configured HTTPS NTLM endpoint.
|
||||
|
||||
## Windows client target
|
||||
|
||||
- Windows 10 22H2 for the lab; Windows 11 is the production target.
|
||||
- Latest .NET 10 x64 runtime. Managed COM hosting cannot be self-contained.
|
||||
- Client certificate with non-exportable private key in `LocalMachine\My`.
|
||||
- Trust for the broker certificate or issuing CA.
|
||||
- Domain membership and DNS resolution for the broker.
|
||||
|
||||
No Visual Studio, compiler, SDK, PowerShell module, or source tree is required on
|
||||
the target client.
|
||||
|
||||
For an isolated target, download the current `Microsoft.DotNet.Runtime.10`
|
||||
offline installer on the development host, verify its publisher/signature, stage
|
||||
it with the provider, and pass its path to `Install-CredentialProvider.ps1`.
|
||||
Reference in New Issue
Block a user