Kerberos Underworld Ondrej Sevecek | MCM: Directory | MVP: Security [email protected] | .
ADFS intranet scenarios - Sevecek
Transcript of ADFS intranet scenarios - Sevecek
2. 3. 2020
1
ADFS and Web Application
Proxy
GOPAS: info@gopas,cz | www.gopas.cz | www.facebook.com/P.S.GOPAS
Ing. Ondřej Ševeček | GOPAS a.s. |MCSM:Directory2012 | MCM:Directory2008 | MVP:Enterprise Security | CEH |
CHFI | CISA |
[email protected] | www.sevecek.com |
ADFS intranet scenarios
2. 3. 2020
2
Web application authentication
Windows authentication
• Kerberos, NTLM
• SSO under domain account
• RSO under any other account or from the internet
• web server domain member
Forms based authentication
• custom login/credentials
• cookies (URL bound, lifetime)
ADFS authentication
• redirect to ADFS server and back
• cookies for ADFS and web
ADFS motivation
Single authenticating server
• trusted account store
• trusted connection
• credentials never “typed” into insecure web services
• SSO over all web applications
Web services easy handling of tokens
• no worry about security
• just a signed piece of XML/JSON
2. 3. 2020
3
Standard web-based authentication
Active Directory Federation Services (ADFS)
HTTP server providing several web based authentication mechanisms• Active Directory (ADDS)
• Active Directory Lightweight Directory Services (ADLDS)
• Azure AD (AAD)
• any third party
Produces claims or cookies in various formats• WS-Trust or SAML-Token for active clients
• WS-Federation (also called SAML 1.0/1.1) and SAML 2.0 for passiveclients
• SAML-P for active/passive clients
• OAuth for semi-passive clients
Required by Office365/AzureAD for on-premises hybrid deployments
Active vs. passive clients
Passive clients
• do not understand XML/SOAP/??? by them
• Internet Explorer, Chrome, FireFox, …
• java script, HTTP 302 redirects
Active clients
• web service knowledgeable clients
• Active Sync, Outlook, Word, …
Current mobile device tech
• active client app + “ask” browser for “cookie”/”token”
2. 3. 2020
4
ADFS version history
Version OS Notes Support
ADFS 1.0 Windows 2003 R2included
runs in IISSAML 1.1
ADFS 1.1Windows 2008
Windows 2008 R2
included
runs in IISSAM 1.1 tokens
ADFS 2.0Windows 2008
Windows 2008 R2
download
runs in IISSAML 2.0 tokens
ADFS 2.1 Windows 2012included
runs in IISdevice registration
ADFS 3.0 Windows 2012 R2
included
direct hosting on HTTP.SYS
TLS SNI support
PowerShell only config (plus HTML/Javascript)
OAuth implicit grant
multifactor auth
password change
/adfs/probe
ADFS 4.0 Windows 2016
admin delegation
own certification authority for device registration
http to https redirection with WAP
http publishing with WAP
OAuth full
OAuth and HTTP basic authentication with WAP
Azure MFA
Microsoft Passport
ADFS 4.1 Windows 2019
custom authentication providers
HTTP headers customization (HSTS, X-Frame-Options)
specify MFA auth method per RP
ADFS certificates
TLS HTTPS certificate• TCP 443, 49433
• signs ECDH or encrypts RSA key exchanges
• should be trusted by all clients
Service communication certificate• by default the same as TLS certificate
• encrypts SOAP message
• must be trusted by all clients
Token signing certificate• signs SAML/OAuth tokens
• must be trusted by all servers as per thumbprint
Token decryption certificate• decrypts SAML/OAuth tokens received from claim providers
• must be trusted by all servers as per thumbprint
2. 3. 2020
5
Note: TLS certificate subject names
Subject• just a single name for backward compatibility
• CN=adfs.gopas.cz
Subject Alternative Name (SAN)• *.gopas.cz
wildcard rules them all :-)
does not match subname.name.gopas.cz
• adfs.gopas.cz at least the ADFS public name
• enterpriseregistration.gopas.cz if device registration is required
• enterpriseregistration.sevecek.eu if device registration is required for other user UPN suffixes
• certauth.adfs.gopas.cz with Windows 2016 no need to use TCP 49443 for certificate
authentication
ADFS installation #1 Buy a public name from public CA
SHA256, RSA 2048, EKU = Server Authentication
TLS certificate key usage = Key Encipherment (TLS 1.0) and/or Digital Signature (requires TLS 1.1+)
Service communication certificate key usage = Key Encipherment
2. 3. 2020
6
ADFS installation #2
ADFS farm behind a load balancer with a
common SQL server
ADFS1
ADFS2
Load
Balancer
Browser
clientBrowser
client
GUI
clientGUI
client
https://adfs.gopas.cz
SQL
2. 3. 2020
7
ADFS farm behind a load balancer with a
common SQL server
ADFS1
ADFS2
Load
Balancer
Browser
clientBrowser
client
GUI
clientGUI
client
https://adfs.gopas.cz
SQL
same
cert
same
cert
TCP
443
Note: if you have 2012 R2 or do not have the certauth DNS SAN name in the web server
TLS certificate you have to balance TCP 49443 as well
ADFS farm behind a load balancer with
individual secondary WID instances
ADFS1
ADFS2
Load
Balancer
Browser
clientBrowser
client
GUI
clientGUI
client
https://adfs.gopas.cz
WID
WID
primary
member
ADFSn
WID
replication
2. 3. 2020
8
ADFS installation #3
ADFS installation #4
Certificate template must NOT be Key Storage Provider
• certutil -repairstore my *
the best Key Usage is Digital Signature and Key Encipherment
2. 3. 2020
9
ADFS service communication certificate notes
Key Storage Provider (CNG, KSP)
• works fine for ADFS by default
• does not work when enabling some endpoints
• e.g. WS-Trust 2005 : password : message
Digital signature key usage is sufficient by default
• but if enabling some endpoints they need Key Encipherment
• e.g. WS-Trust 2005 : password : message
ADFS installation #5
AD DFL must be Windows 2012+
AD Key Distribution Service (KDS) must be provisioned
• Add-KdsRootKey -EffectiveTime ([DateTime]::Now.AddDays(-1))
2. 3. 2020
10
ADFS installation #6
WID supports up to 5 ADFS servers and 60 000 users with more than 100 relying
parties
WID supports up to 30 ADFS servers with less than 100 relying parties
Requires sysadmin in full SQL
• dbcreator and securityAdmin are not sufficient
ADFS installation #7
servicePrincipalName = host/adfs.gopas.cz
• SOAP clients ask for host/SPN instead of http/SPN
msDS-SupportedEncryptionTypes = RC4, AES
2. 3. 2020
11
ADFS installation #8
ADFS installation #9
URI: http://sevecek.com/2016-01/adfs/intranet
URN: urn:oid:1.3.6.1.4.1.25005.7.3
URN: urn:fdc:sevecek.com:201601:adfs-intranet
2. 3. 2020
12
Note: Claim type URNs
URI: http://sevecek.com/2016-01/adfs/intranet/myClaimType
URN: urn:oid:1.3.6.1.4.1.25005.7.3/myClaimType
URN: urn:fdc:sevecek.com:201601:adfs-intranet/myClaimType
ADFS installation #10 (2016+)
2. 3. 2020
13
ADFS installation #11
SsoLifetime
• lifetime of the MSISAuth session cookie by default
KmsiLifetimeMins
• lifetime of the MSISAuth persistent cookie if when KMSI enabled
ADFS installation #12
2. 3. 2020
14
ADFS installation #13
ADFS installation #14
do not forget about certauth.adfs.gopas.cz
2. 3. 2020
15
ADFS installation #15
Port TCP 49443 - client certificate authentication
AdfsTrustedDevices - ADFS proxy (WAP) TLS client trust
ADFS installation #16
Get-AdfsSslCertificate, Set-AdfsSslCertificate
• netsh http show sslcert
• appId = {5d89a20c-beab-4389-9447-324788eb944a}
by default it is the same as the Service communication certificate, but
might be changed separately
• ensure the service-communications certificate is the same
2. 3. 2020
16
ADFS installation #17
TLS client certificate authentication since Windows 2016 can use port 443
• requires certauth.adfs.gopas.cz subject name (rather SAN)
Set-AdfsAlternateTlsClientBinding -Thumbprint
• use if certificate changed later (updates HTTP.SYS UrlAcl as well)
• after the change you can update it with Set-WebApplicationProxySslCertificate on WAP
ADFS installation #18 Renewing/replacing server authentication certificate
2. 3. 2020
17
ADFS installation #19 Assign read private key for NT SERVICE\ADFSSRV and NT SERVICE\DRS
DRS removed on Windows 2016
ADFS installation #20 Service communications certificate
• used to signing WS-Fed/SAML2 tokens and possibly encrypting SOAP messages
Token signing certificate
• self-signed certificate for signing issued tokens
• on web application part trusted per thumbprint
Token decrypting certificate
• self-signed decrypts tokens issued by other AD FS servers
• imported into the other ADFS and used explicitly
Get-AdfsCertificate, Set-AdfsCertificate
2. 3. 2020
18
ADFS installation #21
ADFS installation #22
2. 3. 2020
19
ADFS installation #23
ADFS installation #24
Transport and Mixed endpoints use HTTPS
SOAP Message security does not require HTTPS
2. 3. 2020
20
ADFS installation #25
Enabling/disabling endpoints register them in
HTTP.SYS
ADFS installation #26
ADFS service account must be member of Windows Authorization Access
Group (WAAG) in order to read tokenGroups attributes from AD and use
Kerberos S4U service
• by default all Authenticated Users are members of Pre-Windows 2000 Compatible Access
which limits the need for WAAG
2. 3. 2020
21
ADFS installation #27
Read access in AD
Windows Authorization Access Group (WAAG)
• sufficient for the automatic incoming claims groupSid
• required for any user authentication against AD
Pre-Windows 2000 Compatible Access
• "read-all" on user accounts
• required for LDAP attribute store Token-Groups extractions
ADFS installation #28
On Windows 2016, enable IDPinitiatedSignOn page
to test authentication
• Set-AdfsProperties -EnableIdPInitiatedSignonPage $true
2. 3. 2020
22
ADFS installation #29
Device Registration (10) aka Workplace Join (8.1)
runas Enterprise Admins member
Initialize-ADDeviceRegistration -ServiceAccountgps\gsvc-adfs$
DNS CNAME enterpriseregistration.UserUPNsuffix• or DNS A (SPN not necessary)
gsvc-adfs$ member of Key Admins
Verify forest configuration• CN=Device Registration
Configuration,CN=Services,CN=Configuration,DC=x
• CN=RegisteredDevices,DC=x
ADFS configuration notes
Must be Domain Admins member to install ADFS• some stupid customer requirement
Installer account must be sysadmin in DB if using full SQL
ADFS service account gets servicePrincipalName• Domain Admins can write it, does not require self registration
Creates and AD container• CN=Program
Data,CN=Microsoft,CN=ADFS,CN=CertificateSharingContainer,DC=x
• self-signed certificate private keys are stored here
NETSH HTTP SHOW SSLCERT
NETSH HTTP SHOW SERVICESTATE | findstr :443
ADFS service account must be member of WAAG if user attributes are to be used as filters on incoming claims
2. 3. 2020
23
Simple ADFS terminology
Browser
Client
GUI
Client
ADFS
https://adfs.gopas.cz
DC
GPS
gopas.virtual
WIA (Kerberos)
Basic
Forms
Outgoing claims
Incoming claims
"Cookie" or "token"
Passive client
Active client
SQL
LDAP
Attribute stores
Request
Identity provider
ADFS internal testing
Browser
Client
GUI
Client
ADFShttps://adfs.gopas.cz
DC
GPS
gopas.virtual
TLS Certificate
WIA (Kerberos)
Basic
Forms
2. 3. 2020
24
Testing ADFS from browser
F12 developer toolbar (IE/Edge/Chrome)
• does not show authentication headers
Fiddler with TLS inspection
Ctrl-Shift-DEL clear cookies + temp (only)
Testing ADFS from browser (metadata)
http://adfs.gopas.cz/adfs/probe• anonymous,
• returns 200 OK, Server: Microsoft-HTTPAPI/2.0
https://adfs.gopas.cz/federationmetadata/2007-06/federationmetadata.xml• requires SNI
• WS-Fed / SAML 2.0 metadata
• anonymously available
• digitally signed with XMLDSIG (similar to PKCS#7)
https://adfs.gopas.cz/adfs/services/trust/mex• requires SNI
• WS-Trust metadata
• anonymously available
https://adfs.gopas.cz/adfs/fs/federationserverservice.asmx• requires SNI, anonymous
• ADFS1.0 web service metadata
https://adfs.gopas.cz/adfs/ls• requires SNI, anonymous, returns error HTML with illustration.png
https://adfs.gopas.cz/adfs/ls/idpinitiatedsignon
2. 3. 2020
25
Extract ADFS token signing certificate from XML
Quick ASCII, Base64 and URL reference
[Reflection.Assembly]::LoadWithPartialName('System.Web')
[Web.HttpUtility]::UrlDecode( ' ') # from GET/POST params
[Web.HttpUtility]::UrlEncode( ' ')
[Web.HttpUtility]::HtmlDecode( ' ') # from HTLM FORM field
[Web.HttpUtility]::HtmlAttributeEncode( ' ')
[Web.HttpUtility]::ParseQueryString((New-Object Uri
'https://.../?a=1&b=2&c=3').Query)
# decoding SAMLP
[Text.Encoding]::ASCII.GetString(([Convert]::FromBase64Strin
g(([Web.HttpUtility]::UrlDecode( ' ')))))
%3D = %26 & %2F / %3F ?
%3A : %2B + %3C < %20 space
2. 3. 2020
26
HTTP cookies generally
Name=Value; Name=Value; ...
Path=/subPath• limited to a subpath
Domain=.gopas.cz• can enable cookie from a subdomain to go to other thirt-level subdomains
Expires=23-May-2015 22:13:08 GMT• denotes persistent cookie
Max-Age=[seconds]• expirations in browser are not enforced
• servers expire cookies themselves
Cleaning up a cookie = set empty value + expire
HttpOnly• cannot be used by JavaScript
Secure• requires HTTPS
Web
App
Passive client authentication
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
GET
https://finance
1
Service Provider
Relying PartyIdentity Provider
Claims Provider
2. 3. 2020
27
Web
App
Passive client authentication
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
GET
https://finance
1
302
https://adfs.gopas.cz
2
Service Provider
Relying PartyIdentity Provider
Claims Provider
Web
App
Passive client authentication
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
GET authenticate
https://adfs.gopas.cz
3
Service Provider
Relying PartyIdentity Provider
Claims Provider
2. 3. 2020
28
Web
App
Passive client authentication
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
POST Submit JavaScript
https://finance
4COOKIE: MSISAuth: adfs.gopas.cz
COOKIE: MSISSignOut: adfs.gopas.cz
finance RP
portal RP
office365 RP
XML
claims token
Service Provider
Relying PartyIdentity Provider
Claims Provider
Web
App
Passive client authentication
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
POST Submit JavaScript
https://finance
4COOKIE: MSISAuth: adfs.gopas.cz
COOKIE: MSISSignOut: adfs.gopas.cz
finance RP
portal RP
office365 RP
XML
claims token
POST
https://finance
5
XML
claims token
Service Provider
Relying PartyIdentity Provider
Claims Provider
2. 3. 2020
29
Web
App
Passive client authentication
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
POST Submit JavaScript
https://finance
4COOKIE: MSISAuth: adfs.gopas.cz
COOKIE: MSISSignOut: adfs.gopas.cz
finance RP
portal RP
office365 RP
XML
claims token
POST
https://finance
5
OK
https://finance
6
XML
claims token
COOKIE: FedAuth: finance
Service Provider
Relying PartyIdentity Provider
Claims Provider
Testing ADFS from browser (authentication)
https://adfs.gopas.cz/adfs/ls/idpinitiatedsignon.aspx
https://adfs.gopas.cz/adfs/ls/idpinitiatedsignon
• manually initiated from browser
• file extension does not matter on 2012 R2+
https://adfs.gopas.cz/adfs/ls?wa=wsignin1.0&wtrealm=https://portal.gopas.cz
https://adfs.gopas.cz/adfs/ls/wia?wa=wsignin1.0&wtrealm=urn:fdc:sevecek.com:finance
• WS-Federation passive sign-in URL, you receive SAML1.1 token
• target 302 redirect configured as: WS-Federation Passive Endpoints on the Endpoints tab as
Default
• wtrealm = one of the relying party Identifiers
https://adfs.gopas.cz/adfs/ls?wa=wsignin1.0&wtrealm=urn:fdc:sevecek.com:finance&wr
eply=https://portalinternal.gopas.cz
• wreply = non-default target 302 redirect configured as: WS-Federation Passive Endpoints on
the Endpoints tab
2. 3. 2020
30
WS-Fed URI elements
wtrealm• processed by the ADFS to determine relying party identifier for which the request came
wreply• processed by the ADFS as the desired back redirection
• must match one of the Trusted URLs on the Endpoints tab
wctx, wct• values ignored by ADFS and just passed from requests to replies
• storing client application context values
wauth• &wauth=urn:oasis:names:tc:SAML:1.0:am:password (FBA)
• &wauth=urn:federation:authentication:windows (WIA)
• &wauth=urn:ietf:rfc:2246 (TLS client certificate)
• &wauth=http://schemas.microsoft.com/claims/multipleauthn (request multifactor auth)
whr• home realm claims provider explicitly named in URL
• AD AUTHORITY, urn:fdc:books, ...
Note: ADFS MSISAuth cookie
may be persistent if KMSI enabled on FBA
authentication
• 8 hours session vs. 24 hours persistent
encrypted by ADFS farm wide encryption key
contains only SAM login of the user
• AD lookup is always performed by any ADFS farm member
• uses Kerberos S4U
• always updates group membership and attributes' store
attributes
• if UPN is changed, user is still logged-on
• if SAM is changed, new logon dialog appears
2. 3. 2020
31
Note: application FedAuth cookie
Encrypted by ASP.NET machine encryption keys
By default stores the whole token (claims)
• immune against farm member restart
• shared among farm members
• big
Minimizing the cookie size
• server-side session security token caching
• implementing cache based on SessionSecurityTokenCache
Note: cookie encryption on web server farms
<system.web>
<machineKey
validationKey="SomeSHA1Key"
decryptionKey="SomeAESKey"
validation="SHA1"
decryption="AES"
/>
</system.web>
byte[] utf8encoded = Encoding.UTF8.GetBytes(text);
byte[] protected = MachineKey.Protect(utf8encoded, "salt");
string urlEncoded = HttpServerUtility.UrlTokenEncode(protected);
// MachineKey.Unprotect(protected, "salt")
2. 3. 2020
32
ADFS SSO cookie and RP token lifetime
Default ADFS SSO cookie is 480 minutes (session) or
24 hours (if persistent)
Set-AdfsRelyingPartyTrust -TokenLifetime [minutes]
• default = 0 = 60 minutes!!
signed
Web
App
Token signature only
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
POST Submit JavaScript
https://finance
4
XML
claims token
POST
https://finance
5
XML
claims token
Service Provider
Relying PartyIdentity Provider
Claims Providersigning cert
priv
can read
2. 3. 2020
33
encrypted
signed
Web
App
Token signature and encryption
ADFSWeb
AppWeb
AppWeb
App
Passive
Client
POST Submit JavaScript
https://finance
4
XML
claims token
POST
https://finance
5
XML
claims token
Service Provider
Relying PartyIdentity Provider
Claims Providersigning cert
encryption cert
priv
pub
cannot read
priv
Standards
Name What How Notes
WS-Federationtransport
POST redirectspassive clients
WIF (Windows
Identity
Foundation)
WS-Trust transport active SOAP clients
SAML-P, SAMLP, SAML
protocol
transport
302/POST redirects
passive client
active SOAP clients
ADFS 2.0
no NETFX support
SAML 1.0 XML token formatused by WS-Federationurn:oasis:names:tc:saml:1.0:assertion
ADFS 1.0
SAML 1.1 XML token formatused by WS-Federationurn:oasis:names:tc:saml:1.0:assertion
ADFS 1.1
SAML 2.0 XML token formatused by SAMLPurn:oasis:names:tc:saml:2.0:assertion
ADFS 2.0
OAuthtransport + token
format
active SOAP clients
tokens JWT (JSON Web Token)ADFS 3.0
2. 3. 2020
34
Testing ADFS from browser (authentication)
https://adfs.gopas.cz/adfs/ls?SAMLRequest=deflatedBase64request• SAML2.0 sign-in URL, returns SAML2.0 token
• configured as: SAML Assertion Consumer Endpoints on the Endpoints tab
• you can decode the "invalid" Base64 online at https://idp.ssocircle.com/sso/toolbox/samlDecode.jsp <samlp:AuthnRequest ...
https://adfs.gopas.cz/adfs/oauth2/authorize?response_type=code&client_id=11111111-2222-3333-4444-123456789012&redirect_uri=https://portal.gopas.cz&resource=https://portal.gopas.cz• OAuth sign-in URL, returns OAuth token, only for active clients
• configured as: no endpoint plus use Get-AdfsClient and Add-AdfsClient
Testing ADFS from browser (sign-out)
WS-Federation passive sign-out• https://adfs.gopas.cz/adfs/ls/?wa=wsignout1.0
cleaning up relying party trusts requires sign-out cookie to be generated during logon and always sent back: MSISSignOut
• https://portal.gopas.cz/?wa=wsignoutcleanup1.0
cleans up the sign-out cookie on the claims-aware web site
• https://portal.gopas.cz/?wa=wsignoutcleanup1.0&wreply=https://adfs.gopas.cz/adfs/ls/?wa=wsignout1.0
both in a single URL
SAMLP 2.0 logout request• https://adfs.gopas.cz/adfs/ls/?SAMLRequest=deflatedBase64requ
est
<samlp:LogoutRequest ...
2. 3. 2020
35
Office365 passive client examples WS-Fed
Metadata• https://nexus.microsoftonline-p.com/federationmetadata/2007-
06/federationmetadata.xml
Target endpoints for passive client redirection• https://login.microsoftonline.com/login.srf
Relying party identifiers allowed by Microsoft for WS-Fed• login.windows.net (invalid wtrealm format)
• urn:federation:MicrosoftOnline
• https://login.windows.net
• microsoftonline.com (invalid wtrealm format)
Passive WS-Fed login URI• https://adfs.gopas.cz/adfs/ls/?wa=wsignin1.0&wtrealm=urn:federation:Microso
ftOnline
Signout-cookie MSISSignOut• signoutCleanup;urn:federation:MicrosoftOnline
• Microsoft+Office+365+Identity+Platform
• https://login.microsoftonline.com/login.srf
• https://login.microsoftonline.com/login.srf
Office365 passive client examples SAML-P
Metadata• https://nexus.microsoftonline-
p.com/federationmetadata/saml20/federationmetadata.xml
Target endpoints for passive client redirection• https://login.microsoftonline.com/login.srf
Passive SAML login URI• https://adfs.gopas.cz/adfs/ls/?SAMLRequest=fVHfS8MwEH4X%2FB9C3rM1X
btuRzsYDmHgVJz44Iuk3QUDbVJzqcz%2F3nSizJe9fr%2Fuu7uSVNf2sB7Cu33CjwEpsGPXWoITUfHBW3CKDIFVHRKEBvbr3R2kkwR674JrXMvPLJcdigh9MM5ytt1U%2FK2QhayTOhVyqVOR1SoVC73MRJrVOebzutASo5RowK2loGyoeJrITCRSzJJnOQe5gFn%2BytkLeoq5kZ4knK1%2F59w4S0OHfo%2F%2B0zQx5IDHikfF6vqKsXJsDKd4vxp7azygV6MRdqbxjpwOD7Y1FsvpufbP3MN9XHK7eXStab7YrfOdCpdvMCLmIPRJCv3YmwLawKcx9mfM%2F4dE%2BBs%3D
• <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_7171b0b2-19f2-4ba2-8f94-24b5e56b7f1e" IssueInstant="2014-01-30T16:18:35Z" Version="2.0" AssertionConsumerServiceIndex="0" >
<saml:Issuer>urn:federation:MicrosoftOnline</saml:Issuer><samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
</samlp:AuthnRequest>
2. 3. 2020
36
Updating ADFS singing certificate in Office365/Azure/Intune
Import-Module MSOnline
Get-Credential
Connect-MSOLService
Get-MSOLFederationProperty
Set-MsolADFSContext -Computer localhost -LogFile
• only LAN connection
• PS remoting must be enabled on the ADFS server
Enable-PSRemoting -force on Windows 2008 R2-
Update-MSOLFederatedDomain
Modern Authentication (non-Browser, no MFA) for Office 2013
If not enabled by default, Outlook uses WS-Federation redirection with web page GUI• plus can perform MFA
Install all updates!!!
Enable on clientHKCU\Software\Microsoft\Office\15.0\Common\Identity
EnableADAL = DWORD = 1
Version = DWORD = 1
Enable on Exchange Online$cred = Get-Credential; Connect-MsolService -Cred $cred; Import-Module (Import-PSSession $(New-
PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/
-Credential $cred -Authentication Basic -AllowRedirection) -DisableNameChecking) -Global -
DisableNameChecking
Set-OrganizationConfig -OAuth2ClientProfileEnabled:$true
Enable endpoints on ADFS server
• adfs/services/trust/mex
• adfs/services/trust/2005/windowstransport (enabled by default)
• adfs/services/trust/13/windowstransport (could be used instead)
Cleaning the cache
• delete the whole Identity keyRemove-Item HKCU:\Software\Microsoft\Office\15.0\Common\Identity -Recurse
2. 3. 2020
37
Authenticating into SharePoint
$domain = 'gopas.cz'
$realm = "urn:fdc:$($domain):201609:sharepoint:intranet"
$signIn = "https://adfs.$domain/adfs/ls"
$certFile = '\\dc\public\adfs-{0}-#01.cer' -f $domain.Replace('.', '-')
$idClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
$idClaimName = 'EmailAddress'
$signCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certFile)
New-SPTrustedRootAuthority -Name "$domain ADFS Token Signing Certificate" -Certificate $signCert
$map1 = New-SPClaimTypeMapping -IncomingClaimType $idClaim -IncomingClaimTypeDisplayName
$idClaimName -SameAsIncoming
$map2 = New-SPClaimTypeMapping -IncomingClaimType
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role" -IncomingClaimTypeDisplayName
"Department" -SameAsIncoming
$map3 = New-SPClaimTypeMapping -IncomingClaimType "urn:fdc:sevecek.com:201801:claims/city" -
IncomingClaimTypeDisplayName "City" -SameAsIncoming
$claims = @($map1, $map2, $map3)
$ap = New-SPTrustedIdentityTokenIssuer -Name "$domain ADFS Provider" -Description "$domain ADFS
User Authentication" -realm $realm -ImportTrustCertificate $signCert -ClaimsMappings $claims -
SignInUrl $signIn -IdentifierClaim $idClaim
Authenticating into SharePoint
WS-Federation endpoint
• https://sp.gopas.cz/_trust
SP built-in sign-out
• https://sp.gopas.cz/_layouts/15/SignOut.aspx
WS-Fed sign-out from SP only
• https://sp.gopas.cz/_trust/?wa=wsignoutcleanup1.0
WS-Fed sign-out from ADFS and all apps
• https://sp.gopas.cz/_trust/?wa=wsignout1.0
2. 3. 2020
38
SharePoint cookies
Sliding cookie expiration 50 minutes before RP token
expires$sts = Get-SPSecurityTokenServiceConfig
$sts.LogonTokenCacheExpirationWindow = (New-TimeSpan -Min 50)
$sts.Update();
Using session cookies instead of persistent ones (requires
Office applications re-authentication)$sts = Get-SPSecurityTokenServiceConfig
$sts.UseSessionCookies = $true
$sts.Update()
iisreset
Testing ADFS from browser with Fiddler
Get-AdfsProperties
by default requires extended protection for WIA
Set-AdfsProperties -ExtendedProtectionTokenCheck
None
2. 3. 2020
39
Testing ADFS from browser with FireFox or
Chrome or Edge
Firefox
• disable extended protection for WIA
• type 'about:config', filter for 'ntlm', add 'adfs.gopas.cz' to
'network.automatic-ntlm-auth.trusted-uris' setting
FireFox, Chrome, Edge
• WIASupportedUserAgents
ADFS 3.0 (2012 R2) ADFS 4.0 (2016)
MSIE
MSAuthHost/1.0/In-Domain
Trident/7.0
MSIPC
Windows Rights Management Client
MSAuthHost/1.0/In-Domain
MSIE 6.0
MSIE 7.0
MSIE 8.0
MSIE 9.0
MSIE 10.0
Trident/7.0
MSIPC
Windows Rights Management Client
MS_WorkFoldersClient
=~Windows\s*NT.*Edge
WIA for domain joined computers only
2. 3. 2020
40
Testing ADFS from a GUI client
use Fiddler to decrypt HTTPS
use Windows Identity Foundation to request active
responses
• cannot produce SAML 2.0 (SAML-Protocol) cookie based
responses
Azure MFA
Requires
• Azure AD Premium
• or Intune (Mobile Device Management - MDM)
Users register at:
• https://aka.ms/MFAsetup
App
• Azure Authenticator
2. 3. 2020
41
Initialize Azure MFA on Windows 2016+
$tenant = 'sevecekeu201710.onmicrosoft.com'
$admin = "admin@$tenant"
Connect-MsolService -Cred (Get-Credential $admin)
# Note: this one identifies the AzureMFA service in MSOL
$appId = '981f26a1-7f43-403b-a875-f8b09b8cd720'
# Note: this will be stored with private key in LocalMachine store
# Subject = CN=sevecekeu201710.onmicrosoft.com
# EKU = Client Authentication
$selfSignedCert = New-AdfsAzureMfaTenantCertificate –TenantId $tenant
New-MsolServicePrincipalCredential -AppPrincipalId $appId -Type Asymmetric -
Usage Verify -Value $selfSignedCert
Set-AdfsAzureMfaTenant -TenantId $tenant -ClientId $appId
Requiring MFA for pre-2016 relying parties which
do not use the new Access Control PoliciesGet-AdfsRelyingPartyTrust
Get-AdfsRelyingPartyTrust -Identifier 'urn:federation:MicrosoftOnline'
# Note: Require MFA for all requests
Set-AdfsRelyingPartyTrust -AdditionalAuthenticationRules '=> issue( Type =
"http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod
", Value = "http://schemas.microsoft.com/claims/multipleauthn" );'
# Note: Require MFA for both intranet and extranet
Set-AdfsRelyingPartyTrust -AdditionalAuthenticationRules '
c:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork",
Value == "false"]
=> issue(Type =
"http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod
", Value = "http://schemas.microsoft.com/claims/multipleauthn");
c:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork",
Value == "true"]
=> issue(Type =
"http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod
", Value = "http://schemas.microsoft.com/claims/multipleauthn");'
2. 3. 2020
42
Disable double MFA pop-ups on Azure accounts which
require MFA (older Azure AD Connect installators)
Set-MsolDomainFederationSettings -DomainName gopas.cz -SupportsMfa $true
# Note: forward the claim
# http://schemas.microsoft.com/claims/authnmethodsreferences
# with value
# http://schemas.microsoft.com/claims/multipleauthn
#
# or you get a Loopback Detection error event 364
# => issue(Type =
"http://schemas.microsoft.com/claims/authnmethodsreferences", Value =
"http://schemas.microsoft.com/claims/multipleauthn");
web
serviceweb
service
parameters
POST body
SOAP response
HTTP based or SOAP based
user device
ADFS motivation and GUI applications
ADFS
untrusted
sandboxed
app
web
service
sign-in URL
authenticate
throught the
app
302 Redirect https://webservice
POST Redirect https://webservice
SOAP reply
token with
limited lifetime
2. 3. 2020
43
user device
ADFS motivation and UWA applications
ADFS
trusted
browser
untrusted
sandboxed
app
web
service
sign-in URL
sign-in URL
authenticate
securelly
web
serviceweb
service
web
serviceweb
service
user device
ADFS motivation and UWA applications
ADFS
trusted
browser
untrusted
sandboxed
app
web
service
sign-in URL
sign-in URL
302 Redirect ms-app://localAppID
query
parameters
token with
limited lifetime
authenticate
securellyPOST Redirect ms-app://localAppID
https://finance
2. 3. 2020
44
Claim rules
Claim members
Type• http://schemas.xmlsoap.org/claims/UPN
• urn:fdc:gopas.cz:201701:adfs/someClaim
Issuer• AD AUTHORITY (primarySid, groupSid, ...)
• LOCAL AUTHORITY (authenticationinstant, client cert thumbprint, subject, san, ...)
• SELF AUTHORITY
• urn:fdc:gopas.cz:201606:adfs-intranet
OriginalIssuer
Value
ValueType• http://www.w3.org/2001/XMLSchema#string
• http://www.w3.org/2001/XMLSchema#base64Binary
• http://www.w3.org/2001/XMLSchema#date
• http://www.w3.org/2001/XMLSchema#dateTime
everything is case sensitive by default
more claims of the same type can usually be generated and kept• things such as UPN, Name, windowsaccountname can have more items
• except for NameID claim
• exactly duplicate claims are removed
2. 3. 2020
45
Claim rules (basics)
# general format to add outgoing claim (no OR operator exists)
# == equals (case sensitive), =~ match regex, $ end of string, ^
start of string, (?i) ignore case, != not equals, !~ not maches
regex
c1:[] && c2:[] => issue( ... c1.Value);
c1:[ Type == "...", Value == "..." ] &&
c2:[ Type == "...", Value =~ "..." ] &&
c3:[ Type == "..." ]
=> issue( Type = "...", Value = "..." + c1.Value )
issue( Issuer = c1.Issuer, OriginalIssuer = "..." )
Type == ".../multivalue", Value =~ "oneValue|secondValue"
Type == ".../ip", Value =~ "10\.10\.+"
Claim rules (basics)
# unconditional condition :-)
c1:[ ]
# copy the claim into outgoing claims
=> issue( claim = c1 );
2. 3. 2020
46
Claim rules (aggregates)
# claim rules trigger for each individual incoming claim of the
same type, possibly issuing more claims
exists() && exists() && not exists() => issue()
exists([ ... ])
exists([
Type == "http://schemas.microsoft.com/2012/...", Value == "..."
])
count([ ... ]) >= 2
count([ Type == "http://contoso.com/proxyAddresses" ]) >= 2
count([ Type == "...", Value == "..." ]) >= 2
Claim rules (examples)
# user coming over proxy
exists([Type ==
"http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-
proxy"])
# specific authentication endpoint
exists([Type ==
"http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-
endpoint-absolute-path", Value ==
"/adfs/services/trust/2005/usernamemixed"])
# passive endpoint
exists([Type ==
"http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-
endpoint-absolute-path", Value == "/adfs/ls/"])
# group membership by SID
exists([Type ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid",
Value == "S-1-5-21-domain-RID"])
2. 3. 2020
47
Claim rules (examples)
# deny request
=> issue(Type =
"http://schemas.microsoft.com/authorization/claims/deny", Value =
"true");
# test for claim issuer
=> c:[Type ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsacc
ountname", Issuer == "AD AUTHORITY"]
Claim rules (advanced)
# Value expressions
= "..." + c1.Value + " ..."
= regexreplace(c1.Value, "...", "...")
# add claim among incoming claims to allow further processing
=> add(...)
2. 3. 2020
48
Claim rules for Office365
c:[Type ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
=> issue(store = "Active Directory", types =
("http://schemas.xmlsoap.org/claims/UPN",
"http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID"),
query = "samAccountName={0};userPrincipalName,objectGUID;{1}",
param = regexreplace(c.Value, "(?<domain>[^\\]+)\\(?<user>.+)", "${user}"),
param = c.Value);
c:[Type ==
"http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID"]
=> issue(Type =
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
Value = c.Value,
Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/fo
rmat"] = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified");
Claim rules for Office365 (password expiration)
c1:[Type == "http://schemas.microsoft.com/ws/2012/01/passwordexpirationtime"]
issue(
store = "_PasswordExpiryStore",
types = (
"http://schemas.microsoft.com/ws/2012/01/passwordexpirationtime",
"http://schemas.microsoft.com/ws/2012/01/passwordexpirationdays",
"http://schemas.microsoft.com/ws/2012/01/passwordchangeurl"
),
query = "{0};",
param = c1.Value
);
2. 3. 2020
49
Additional chaotic notes
Old ADFS 2.0 notes
IIS web site can use HTTP redirection to speed up
login URL
• disable redirection on the ADFS application
Powershell ADFS module needs manual import
• Add-PSSnapIn Microsoft.Adfs.PowerShell
2. 3. 2020
50
ADFS certificates additional notes
CRL checks
• in order to be able to revoke the ADFS signing certificates
Self-signed certificates
• private keys stored in AD
• auto rollover enabled, but must be trusted by the other party
• Set-AdfsProperties -CertificateDuration
• Update-AdfsCertificate -Urgent
• Set-ADFSRelyingPartyTrust -
EncryptionCertificateRevocationCheck -
SigningCertificateRevocationCheck
ADFS farm member synchronization
Get-ADFSSyncProperties
• Get-ADFSSyncConfiguration on ADFS 2.0
Preferred to use Windows Internal Database on each
farm member separately
• can use remote SQL server
Secondaries sync from primary ADFS read/write
server over HTTP or HTTPS
• by default once per 5 minutes
• http://primaryadfs.gopas.virtual/adfs/services/policystoretran
sfer (SOAP) or WCF
net.tcp://primaryadfs.gopas.virtual:1500
• Set-ADFSSyncProperties -PollDuration
2. 3. 2020
51
ADFS farm certificate requirements
Single SSL certificate thumbprint is stored in
configuration
• all ADFS servers must use the same TLS certificate and the
same Service Communication certificate
In case of WIA through WAP with Extended
protection for authentication enabled
• the WAP servers must use the same TLS certificates as the
back-end ADFS servers
Password Change portal for intranet clients?
2. 3. 2020
52
ADFS web pages visual customizations
Cannot customize clientLogon.aspx nor discoverClientRealm.aspx on ADFS 3.0 anymore
Set-AdfsGlobalWebContent
Set-AdfsWebTheme• CompanyName
• Logo
• Illustration
• StyleSheet
• ErrorPageDescriptionText
• ErrorPageAuthorizationErrorMessage
• ErrorPageSupportEmail
Customizing onload.js
# cannot modify the script on the Default theme
New-AdfsWebTheme -Name gopas -SourceName Default
Export-AdfsWebTheme Default -Directory c:\temp\theme
# update the onload.js
Set-AdfsWebTheme -TargetName gopas -OnLoadScript
c:\temp\theme\scripts\onload.js
Set-AdfsWebConfig -ActiveTheme gopas
2. 3. 2020
53
ADFS home real discovery (HRD) pages
customizations
Add UPN suffixes for easier startup• Set-AdfsClaimsProviderTrust -TargetName thePartner -
OrganizationalAccountSuffix 'book-vendors.com'
IdP list per relying party• Set-AdfsRelyingPartyTrust -Target finance -ClaimsProvider 'Active
Directory', 'BOOKS'
Disable HRD for intranet locations• Set-AdfsProperties -IntranetUseLocalClaimsProvider $true
HRD cookie lifetime• Set-AdfsWebConfig -HRDCookieLifetime
Rename "Active Directory" claims provider• customize onload.js
Alternative attribute stores
LDAP connection string
• LDAP://localhost:11111/cn=Users,o=GOPAS
• ADFS authenticates against ADLDS with its service account
SQL server connection string
• Server=DATA;Database=CrmData;Integrated
Security=True;Encrypt=True
2. 3. 2020
54
SQL server table as an alternative attribute store
fullSAM:[
Type ==
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
]
=> add(
store = "infosys" ,
types = ("urn:fdc:gopas.cz:201805:claims/email") ,
query = "SELECT mail FROM People WHERE adlogin = {0}" ,
param = fullSAM.value
)
ADFS extranet scenarios with
WAP reverse HTTPS proxy
2. 3. 2020
55
Motivation
TMG (ISA) discontinued
• TCP/IP/ICMP/IPSec/etc. inspection fully replaced with
Windows Firewall
• intrusion prevention filters included in Windows Defender
and Microsoft Security Essentials
• problematic expansion of reverse HTTPS publishing
Secure reverse HTTPS publishing
• Windows authentication at network perimeter
• Forms-based (cookie) authentication with non-browser
fallback to Basic and/or persistent cookie
Principal scenario – claims aware web applications
(internal HTTP or HTTPS)
Web
Server
Browser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
Web
ServerWeb
Server
TLS Certificate
TLS Certificate
TLS Certificate
TLS Certificate
https://finance.gopas.cz
https://finance
GPS
gopas.virtual
Reverse
HTTPS
Proxy
TLS Certificate
https://adfs.gopas.cz
ADFS
https://finance.gopas.virtual
2. 3. 2020
56
Principal scenario – claims aware web applications
(internal HTTP or HTTPS)
Web
Server
Browser
Client
GUI
Client
WAP
DCDC
Web
ServerWeb
Server
TLS Certificate
TLS Certificate
TLS Certificate
TLS Certificate
https://finance.gopas.czhttps://finance
GPS
gopas.virtual
TLS Certificate
https://adfs.gopas.cz
ADFS
https://finance.gopas.virtual
Principal scenario - Basic authentication web applications
(internal HTTP or HTTPS)
Web
Server Browser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
Web
ServerWeb
Server
TLS Certificate
https://portal.gopas.cz
GPS
gopas.virtual
http://portal
basic
basic
ADFS
basic
2. 3. 2020
57
Principal scenario - Windows authentication web
applications (internal HTTP or HTTPS)
WAP as domain member
Web
Server Browser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
Web
ServerWeb
Server
TLS Certificate
https://portal.gopas.cz
GPS
gopas.virtual
http://portal
full ADFS
Kerberos
ADFS
Principal scenario - Windows authentication web
applications (SharePoint, Exchange, AAM)
Web
ServerBrowser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
Web
ServerWeb
Server
TLS Certificate
https://intranet.gopas.cz
http://intranet
GPS
gopas.virtual
2. 3. 2020
58
Principal scenario – Windows/claims web applications
(no AAM necessary)
Web
ServerBrowser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
Web
ServerWeb
Server
TLS Certificate
TLS Certificate
TLS Certificate
TLS Certificate
https://sp.gopas.cz
GPS
gopas.virtual
https://sp.gopas.cz
Another bit of motivation
SharePoint
not everything requires authentication
HTTP level protocol exploits
• many many many IIS modules to pass
2. 3. 2020
59
Reverse HTTPS proxy general requirements
Require HTTPS from client• possibly redirect to secure traffic
• rather do not redirect to discourage HTTPS strip
• minimize number of public TLS certificates
Decrypt HTTPS at the perimeter• possibly inspect, define rules or extend with third-party
• translate external URI to internal host names and paths
• forward different host header
Authenticate users at the perimeter• Windows authentication against Active Directory
• allow other authentication databases if necessary
Forward user credentials to the application• Windows authentication (WIA) delegation with Kerberos
• claims with Windows Identity Foundation
Web Application Proxy
Require HTTPS from client• possibly redirect to insecure traffic (since 2016 only)
• rather do not redirect to discourage HTTPS strip
• minimize number of public TLS certificates
Decrypt HTTPS at the perimeter• possibly inspect, define rules or extend with third-party
• translate external URI to internal host names and paths
• forward different host header
Authenticate users at the perimeter• Windows authentication against Active Directory
• allow other authentication databases if necessary
Forward user credentials to the application• Windows authentication delegation with Kerberos
• claims with Windows Identity Foundation
TLS SNI as a bonus over TMG• plus Extended Protection for Authentication (NTLM mutual authenitcation)
2. 3. 2020
60
Publishing ADFS through WAP
can use different TLS certificates for most scenarios
must use the same DNS name
Browser
Client
GUI
Client
WAP
DCDC
TLS Certificate
ADFS
TLS Certificate
https://adfs.gopas.cz
https://adfs.gopas.cz
Publishing ADFS through WAP
use the same TLS certificate for WAP for TLC client
authentication
Browser
Client
GUI
Client
WAP
DCDC
TLS Certificate
ADFS
TLS Certificate
https://adfs.gopas.cz
https://adfs.gopas.cz
2. 3. 2020
61
WAP installation #1 (WAP as domain member)
certificate export using ADDS KDS
WAP installation #2
Add-WindowsFeature Web-Application-Proxy, RSAT-
RemoteAccess
2. 3. 2020
62
WAP installation #3
Admin$ on the primary ADFS server
• after installation HTTPS:443 only (TLS client cert.auth.)
WAP installation #4
Note: will use Kerberos even for SMB
• SPN host/adfs.gopas.cz
2. 3. 2020
63
WAP installation #5
WAP installation #6 (on ADFS server)
2. 3. 2020
64
WAP installation #7 (WAP own client certificate)
5 (2012 R2) or 14 (2016+) days validity
WAP to ADFS client authentication
certificates
Browser
Client
GUI
Client
WAP
DCDC
TLS Certificate
ADFS
TLS Certificate
https://adfs.gopas.cz
https://adfs.gopas.cz
WAP
Client
Cert
2. 3. 2020
65
WAP installation #8 (WAP trusted on ADFS server)
WAP installation #9 (ADFS certificates and URL on WAP)
Get-WebApplicationProxyConfiguration• ADFSTokenSigningCertificatePublicKey, ConfigurationChangesPollingIntervalSet = 30
• uses ADFS endpoints: https://adfs.gopas.cz/adfs/Proxy/webapplicationproxy/... and
https://adfs.gopas.cz/adfs/Proxy/EstablishTrust
2. 3. 2020
66
WAP installation #10
testing ADFS access from internet
• https://adfs.gopas.cz/FederationMetadata/2007-06/FederationMetadata.xml
• https://adfs.gopas.cz/adfs/services/trust/mex
• https://adfs.gopas.cz/adfs/ls/IdpInitiatedSignOn
• https://adfs.gopas.cz/adfs/fs/FederationServerService.asmx
HTTP 503 service unavailable
WAP installation #11 (ADFS 2012 R2 extranet lockout)
Prevent external account lockout with lower threshold than
what is on AD
• Set-AdfsProperties -EnableExtranetLockout
• checks only AD account for badPwdCount, badPasswordTime
(prefers PDC if available)
• WAAG not enough, use PW2000CA group
2. 3. 2020
67
WAP installation #12
pass-through benefits?
• updated and terminated TLS/SSL client <-> WAP
• basic HTTP validation and reconstruction
• HTTP to HTTPS redirection
WAP installation #13
HTTP basic
• CLIENT <-> WAP <-> WEB ... HTTP basic
• WAP <-> ADFS ... HTTP basic with https://adfs.gopas.cz/adfs/proxy/relyingpartytoken endpoint
• similar to pass-through with perimeter pre-authentication and ADFS access policies
2. 3. 2020
68
WAP installation #14
WAP certificate notes
Its own self-signed TLS client certificate
Validates the ADFS TLS server certificate
Does not use or validate the ADFS token-signing or
token-decryption certificates when doing ADFS proxy
Does validate ADFS token-signing certificates for
published web applications
• updates automatically from federation metadata• Set-WebApplicationProxyConfiguration -ADFSTokenSigningCertificatePublicKey
2. 3. 2020
69
How ADFS knows what is internal and what
is an external client
ADFS proxy must forward requests with x-ms-proxy
and x-ms-endpoint-absolute-path
• you cannot simply proxy internal WAP-ADFS
communication with Fiddler, because it is mutually
authenticated
Any reverse web proxy supported, not just WAP
WAP own special sign-in URL + redirect
Special ADFS login URL for WAP
• https://adfs.gopas.cz/adfs/ls?version=1.0&action=signin&realm=ur
n%3AAppProxy%3Acom&appRealm=guidguid-guid-guid-guid-
guidguidguid
• appRealm = Get-AdfsRelyingPartyTrust | select ObjectIdentifier
Results in simple HTTP 307 Redirect with the token
encoded in the ?authToken=JWT~1000characters
Gets replaced with EdgeAccessCookie cookie on the first
passage
• never reaches the back-end web application
2. 3. 2020
70
WAP published application with different host name
ADFS itself generates correct absolute URL into the POST FORM
ACTION as long as the wreply parameter is "valid"
Hidden WAP relying party and EdgeAccessCookie
timeout (default 60 minutes)
Set-AdfsWebApplicationProxyRelyingPartyTrust -TokenLifetime
2. 3. 2020
71
WAP installation #15
WAP installation #16
WAP own access policy to limit access to all published web sites
2. 3. 2020
72
WAP publishing #17 (ADFS loopback detection)
Set-AdfsProperties -EnableLoopDetection
• cookie MSISLoopbackDetection
WAP publishing #16 (testing ADFS loop detection)
2. 3. 2020
73
WAP publishing #17 (persistent cookies)
Set-AdfsProperties -EnableKmsi
• "keep me signed in"
Set-AdfsProperties -KmsiLifetimeMins
Set-AdfsProperties -PersistentSsoCutoffTime <DateTime>
• if you want to make all persistent cookies issued before the
datetime invalid
WAP publishing #18 (enable password change page)
Enable updatepassword endpoint
• https://adfs.gopas.cz/adfs/portal/updatepassword
2. 3. 2020
74
WAP publishing #19
Enable sign-out from Web Application Proxy
• by default EdgeAccessCookie does not get deleted when
signing out of any published application
Set-WebApplicationProxyApplication -EnableSignout
• EdgeAccessCookie gets deleted with the
?wa=wsignoutcleanup1.0 action (with the final signout after
all applications)
Client TLS certificate authentication
trusted CA chain
CRL/OCSP validation
issuing CA is NTAuth
client certificate
• Subject = <not relevant>
• Subject Alternative Name (SAN) = [email protected]
extensions
• Key Usage = Digital Signature
• Enhanced Key Usage (EKU) = Client Authentication
2. 3. 2020
75
Client TLS certificate private key storage
TPM protection only• no PIN
• no smart card logon (no Kerberos PKINIT)
• hardware bound, non-exportable, attestation
• KSP: Microsoft Platform Crypto Provider
TPM virtual smart card• PIN
• smart card logon (Kerberos PKINIT)
• more cards for testing removable cards/tokens
• hardware bound, non-exportable
• CSP: Microsoft Base Smart Card Crypto Provider
• KSP: Microsoft Smart Card Key Storage Provider
Virtual TPM smart cards (TPMVSCMGR)
2. 3. 2020
76
More TPM cards
MFA for all WAP access
Set-AdfsWebApplicationProxyRelyingPartyTrust
-AdditionalAuthenticationRules '
=> issue(
Type =
"http://schemas.microsoft.com/ws/2008/06/identity/clai
ms/authenticationmethod",
Value =
"http://schemas.microsoft.com/claims/multipleauthn"
);
'
2. 3. 2020
77
Publishing SharePoint or some other web
applications
Best practice to run internal SP web on public name
since the very start
• SharePoint must know the host name that client uses
Running SharePoint on internal name
• WAP should always forward with the external host header
• WAP cannot define different host header for a different
internal name/IP translation
• WAP must use HOSTS or internal DNS records
Scenario for SharePoint publishing
ok if non-host header web binding or the same
public/private host header (maybe AAM)
Web
ServerBrowser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
Web
ServerWeb
Server
TLS Certificate
https://sp.gopas.cz
https://sp.gopas.cz
GPS
gopas.virtual
https://sp.gopas.czhost header
http://<any>
2. 3. 2020
78
Extend web application first (maybe AAM)
for host header web binding
Web
ServerBrowser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
Web
ServerWeb
Server
TLS Certificate
https://sp.gopas.cz
http://intranet
GPS
gopas.virtual
http://sp.gopas.cz
https://sp.gopas.cz
WAP for WIA applications with
Kerberos delegation
2. 3. 2020
79
Wait. First make Kerberos work internally
AppPool Kernel Mode Authentication AD Account for Kerberos
Local System
(SYSTEM)on/off GPS\WFE$
Local Service
(NT AUTHORITY\Local Service)on/off no Kerberos
Network Service
(NT AUTHORITY\Network Service)on/off GPS\WFE$
ApplicationPoolIdentity
(IIS APPPOOL\apppool)on/off GPS\WFE$
GPS\svc-iis-canteen on GPS\WFE$
GPS\svc-iis-finance off GPS\svc-finance
SPS\sp-intranet-web off GPS\sp-intranet-web
Wait. First make Kerberos work internally
Web server WFE
Web application accessible at http://portal
Application pool running under ApplicationPoolIdentity
IIS Windows Authentication enabled, Kernel Mode Authentication enabled
DNS name portal.gopas.virtual = A
Set servicePrincipalName (SETSPN) on WFE• http/portal
• http/portal.gopas.virtual
2. 3. 2020
80
Wait some more. Yet make Kerberos work
internally even for SharePoint
Web server SP
Web application accessible at http://intranet
Application pool running under sp-intranet-web
IIS Windows Authentication enabled, Kernel Mode Authentication disabled
DNS name intranet.gopas.virtual = A
Set servicePrincipalName (SETSPN) on sp-intranet-web• http/intranet
• http/intranet.gopas.virtual
External authentication
Browser
Client
GUI
Client
Reverse
HTTPS
Proxy
DCDC
TLS Certificate
Basic
Windows NTLM
Windows Kerberos
Forms/cookie
TLS client certificate
2. 3. 2020
81
External authentication challenges
External authentication Facts Internal forwarding Notes
Basic
plain-text
TLS encrypted
no SSO
easy
no browser sign-out no
timeout
non-browser clients
Windows NTLM SSOKerberos constrained
delegation
complicated
sensitive
Windows Kerberosnot possible without
direct contact with DC
Kerberos constrained
delegation
impossible
except for KDC Proxy
Forms/cookie
plain-text
no SSO
session vs. persistent
cookie
easy
claims SAML token
sign-out
timeout
browser clients
TLS client certificate
safe against password
guessing
safe against HTTP
exploits
Kerberos constrained
delegation
claims SAML token
only for "partners"
can use smart-cards
both clients
Scenario with an authentication server
Web
ServerBrowser
Client
GUI
Client
WAP
DCDC
Web
ServerWeb
Server
TLS Certificate
TLS Certificate
TLS Certificate
TLS Certificate
https://portal.gopas.cz
http://portal
RADIUS
?
http://portal.gopas.virtual
2. 3. 2020
82
Scenario with ADFS authentication server
Web
ServerBrowser
Client
GUI
Client
WAP
DCDC
Web
ServerWeb
Server
TLS Certificate
TLS Certificate
TLS Certificate
TLS Certificate
https://portal.gopas.cz
https://portal
ADFS
TLS Certificate
Publishing simple WIA web application
Web
ServerBrowser
Client
GUI
Client
WAP
DCDC
Web
ServerWeb
Server
TLS Certificate
https://portal.gopas.cz
http://portal
ADFS
TLS Certificate
https://adfs.gopas.cz
Kerberos Delegation
2. 3. 2020
83
Kerberos delegation requirements
Kerberos working internally WAP-WEB
• http/portal
• http/portal.gopas.virtual
• or any arbitrary SPN specified in the WAP configuration
Kerberos delegation for WAP server
• Trust this computer to specified services only, Use any
authentication protocol
• WAP member of Windows Authorization Access Group
(WAAG)
• restart WAP machine
ADFS and WAP AD requirements
2. 3. 2020
84
Enable Kerberos delegation on WAP server account
Third-parties aka claim
providers
2. 3. 2020
85
AD
Claim provider trusts
Web
Partner
client
Our
client
Our
ADFSPartner
ADFS
https://finance
https://finance
AD
Claim provider trusts
Web
Partner
client
Our
client
Our
ADFSPartner
ADFS
https://adfs.gopas.cz
https://adfs.gopas.cz
2. 3. 2020
86
AD
Claim provider trusts
Web
Partner
client
Our
client
Our
ADFSPartner
ADFS
https://adfs.gopas.cz
https://adfs.book-vendors.com
AD
Claim provider trusts
Web
Partner
client
Our
client
Our
ADFSPartner
ADFS
outgoing claims
identity
provider
2. 3. 2020
87
AD
Claim provider trusts
Web
Partner
client
Our
client
Our
ADFSPartner
ADFS
outgoing claimsincoming claims
identity
providerrelying
party
AD
Claim provider trusts
Web
Partner
client
Our
client
Our
ADFSPartner
ADFS
outgoing claimsincoming claimsoutgoing claims
identity
provideridentity
providerrelying
party
2. 3. 2020
88
AD
Claim provider trusts
Web
Partner
client
Our
client
Our
ADFSPartner
ADFS
outgoing claimsincoming claimsoutgoing claimsincoming claims
identity
provideridentity
providerrelying
party
relying
party
Workplace join aka
Device registration
2. 3. 2020
89
Initialize-ADDeviceRegistration
requires Enterprise Admins membership
add svc-adfs$ into Key Admins group in the
respective domain or into Enterprise Key Admins
group in forest root domain
• read/write msDS-KeyCredentialLink
CN=DeviceRegistrationService,CN=Device Registration Services,CN=Device
Registration Configuration,CN=Services,CN=Configuration
2. 3. 2020
90
CN=Registered Devices
Enable-AdfsDeviceRegistration
# Note: ADFS 2012 R2 only
Enable-AdfsDeviceRegistration
# Note: ADFS 2012/2016/2019/...
# enables the device registration
# in order to authenticate computers you need to enable the
# Device Authentication in authentication policies
Set-AdfsGlobalAuthenticationPolicy -DeviceAuthenticationEnabled
$true
2. 3. 2020
91
Device registration enabled in ADFS
Device Registration - Register domain joined computers as devices
2. 3. 2020
92
Workplace Join (Windows 8.1) obsolete
Events• Application and Service Logs
Microsoft– Windows
Workplace Join
Tasks• Microsoft
Windows– Workplace Join
autoworkplace.exe join (only with a logged-on user)
triggered when a user logs in interactively
uses local ADFS (user's UPN suffix)• https://adfs.gopas.cz/EnrollmentServer/DeviceEnrollmentWebService.svc
• https://adfs.gopas.cz/adfs/oauth2/...
• authenticates as user
Device Registration (Windows 10)
register on-prem only• searches AD for serviceConnectionPoint
• normally in CN=Device Registration Configuration,CN=Services,CN=Configuration,DC=X
• CN=62A0FF2E-97B9-4513-943F-0D221BD30080
keywords: enterpriseDrsName:enterpriseregistration.gopas.cz
always register into Azure (sync write-back for local ADFS)• searches AD for serviceConnectionPoint
• normally in CN=Device Registration Configuration,CN=Services,CN=Configuration,DC=X
• CN=62A0FF2E-97B9-4513-943F-0D221BD30080
keywords: azureADName:gopas.cz
keywords: azureADId:GUIDGUID-GUID-GUID-GUID-GUIDGUIDGUID of AAD TenantID
Events• Application and Service Logs
Microsoft– Windows
User Device Registration
Tasks• Microsoft
Windows– Workplace Join
dsregcmd (runs under SYSTEM, use dsregdns /status)
triggered when a user logs in interactively (uses its UPN suffix)
uses local ADFS (what comes from AAD as redirected)• https://adfs.gopas.cz/adfs/services/trust/2005/windowstransport
• authenticates as COMPUTER$
2. 3. 2020
93
DSREGCMD parameters
[no parameter]• must run under SYSTEM
• tries to register if AD contains CN=62a0ff2e-97b9-4513-943f-0d221bd30080
/debug• must run under SYSTEM
• debug output for [no parameter] operation
/status• actual status (no network connections)
/leave
/trigger• triggers the scheduled task [no parameter] instead of doing the
operation under SYSTEM account directly
Workplace joined (Win8.1) device object (msDS-Device) and user's
certificate - The first user registers the device
2. 3. 2020
94
Device registered (Win10) certificates in computer store
Device registered (Win10) as msDS-Device
(altSecurityIdentities)
2. 3. 2020
95
Device registered (Win10) certificate published on
computer account
Workplace join or Device registration authentication
always Windows Integrated (WIA)• regardless of Authentication Methods
• MUST not require MFA for Windows 10 which authenticates as machine$ and cannot display MFA web page
Kerberos if possible• CNAME or A, both go to https://adfs.gopas.cz/adfs/oauth2,
additional SPN not necessary
During CTRL-ALT-DEL logon Azure logon is performed as well• https://adfs.gopas.cz/adfs/services/trust/13/usernamemixed
• under gps\kamil + password
2. 3. 2020
96
ADFS certificate Registration Authority (RA aka
Enrollment Agent)
Set-AdfsCertificateAuthority
-EnrollmentAgent
-EnrollmentAgentCertificateTemplate GOPASADFSEnrollmentAgent
-LogonCertificateTemplate GOPASADFSLogon
-WindowsHelloCertificateTemplate GOPASWHFBLogon
• the EnrollmentAgent template must have Subject - Supply in the request, must be KSP
• the Logon template is user type, EKU Client Authentication, must be KSP
• the WhbLogon template is user type, EKU Smart Card Logon, Subject UPN from AD, must be
KSP
certutil -dsTemplate GOPASWHFBLogon msPKI-Private-Key-Flag
+CTPRIVATEKEY_FLAG_HELLO_LOGON_KEY
ADFS certificates are on disk only (not in the service's store at all)
• certutil c:\Users\svc-
adfs$\AppData\Roaming\Microsoft\SystemCertificates\My\Certificates\<thumbprint>
Windows Hello for Business (WHB) on-prem
deployment
2. 3. 2020
97
OAuth 2.0
Basic motivation
Just another redirection protocol
• “implicit grant”
Different token format JWT
• JSON Web Tokens
• simpler and smaller
Refresh tokens
• issue a new access token
based on a previously
obtained refresh token
2. 3. 2020
98
Resource Owner
Client C
Web shop
Client A
Protected Resource
More complex motivation
GUI or Browser
Bank w
eb
serv
ice
Bank DB
services
Monthly
payment for
electricity
Client B
Random
payment for train
tickets
password
pwd
pwd
pwd
pwd
pwd
pwd
• Too permanent password which cannot be changed easily
• Cannot revoke single client
• Password exposed to questionable services
• User may have direct access to the protected resource
Resource Owner
Client C
Web shop
Client A
Protected Resource
More complex motivation
GUI or Browser
Bank w
eb
serv
ice
Bank DB
services
Monthly
payment for
electricity
Client B
Random
payment for train
tickets
Authorization
Server
password
pwd
Authorization Grant
Authorization Grant
Authorization Grant
2. 3. 2020
99
Resource Owner
Client C
Web shop
Client A
Protected Resource
More complex motivation
GUI or Browser
Bank w
eb
serv
ice
Bank DB
services
Monthly
payment for
electricity
Client B
Random
payment for train
tickets
Authorization
Server
password
pwd
Authorization Grant
Authorization Grant
Authorization Grant
Access Token
Access Token
Access Token
Resource Owner
Client C
Web shop
Client A
Protected Resource
More complex motivation
GUI or Browser
Bank w
eb
serv
ice
Bank DB
services
Monthly
payment for
electricity
Client B
Random
payment for train
tickets
Authorization
Server
password
pwd
Authorization Grant
Authorization Grant
Authorization Grant
Access Token
Access Token
Access Token
kamil A
kamil B
kamil C
2. 3. 2020
100
Resource Owner
Client C
Web shop
Client A
Protected Resource
More complex motivation
GUI or Browser
Bank w
eb
serv
ice
Bank DB
services
Monthly
payment for
electricity
Client B
Random
payment for train
tickets
Authorization
Server
password
pwd
Authorization Grant
Authorization Grant
Authorization Grant
Access Token
Access Token
Access Token
kamil A
kamil B
kamil C
kamilA bank
kamilC bank
Client types
Confidential
• server application which can protect its own credentials
• usually using the authorization grant
Public
• mobile application on the resource owner device
• usually using implicit grant (just like WS-Fed or SAML-P)
• resource owner has access to the client credentials
• native application - GUI, sand-boxed or not
• user-agent based application - JavaScript in browser
2. 3. 2020
101
https://adfs.gopas.cz/adfs/oauth2/authorize
Simple redirection with public client
ADFS
resource
owner
web application
client app B
GUI or
browser app
authentication request
authorization
endpoint
https://FrontEndWebAppB.sevecek.com
GET
Simple redirection with public client
ADFS
resource
owner
web application
client app B
authentication request
code grant
GUI or
browser app
https://FrontEndWebAppB.sevecek.com
GET
2. 3. 2020
102
Complex redirection with public client
ADFS
resource
owner
web service
client app B
authentication request
GUI or
browser app
access token request
token
endpoint
https://adfs.gopas.cz/adfs/oauth2/token
https://FrontEndWebAppB.sevecek.com
GET
POST
code grant
as Kamil
Complex redirection with confidential client
ADFS
resource
owner
web service
client app B
authentication request
GUI or
browser app
access token request
token
endpoint
https://adfs.gopas.cz/adfs/oauth2/token
https://FrontEndWebAppB.sevecek.com
GET
POST
code grant
as Kamil
as ClientAppB
2. 3. 2020
103
https://adfs.gopas.cz/adfs/oauth2/authorize
Complex redirection with confidential or public client
ADFS
resource
owner
web service
client app B
GUI or
browser app
Protected
resource server
authentication request
authorization
endpoint
https://FrontEndWebAppB.sevecek.com
https://portal.gopas.cz
GET
https://adfs.gopas.cz/adfs/oauth2/authorize
Complex redirection with confidential or public client
ADFS
resource
owner
web service
client app B
GUI or
browser app
Protected
resource server
authentication request
authorization
endpoint
https://FrontEndWebAppB.sevecek.com
https://portal.gopas.cz
ms-app://localAppOnTheClientMachine
https://localJavaScriptDummyToken/id
GET
2. 3. 2020
104
Complex redirection with confidential or public client
ADFS
resource
owner
web service
client app B
Protected
resource server
authentication request
authorization / code grant
GUI or
browser app
https://FrontEndWebAppB.sevecek.com
ms-app://localAppOnTheClientMachine
https://localJavaScriptDummyToken/id
https://portal.gopas.cz
GET
Complex redirection with confidential or public client
ADFS
resource
owner
web service
client app B
Protected
resource server
authentication request
GUI or
browser app
access token request
token
endpoint
https://adfs.gopas.cz/adfs/oauth2/token
https://FrontEndWebAppB.sevecek.com
ms-app://localAppOnTheClientMachine
https://localJavaScriptDummyToken/id
https://portal.gopas.cz
GET
POST
authorization / code grant
2. 3. 2020
105
Complex redirection with confidential or public client
ADFS
resource
owner
web service
client app B
Protected
resource server
authentication request
GUI or
browser app
access token request
access requesthttps://FrontEndWebAppB.sevecek.com
ms-app://localAppOnTheClientMachine
https://localJavaScriptDummyToken/id
https://portal.gopas.cz
GET
POST
authorization / code grant
The authorization requests
GET
https://adfs.gopas.cz/adfs/oauth2/authorize?response_type=code&client_id=12345678-
2222-3333-4444-123456789012&redirect_uri=ms-
app://localAppOnTheClientMachine&resource=https://backEndSharedWebService.gopas.c
z
GET
https://adfs.gopas.cz/adfs/oauth2/authorize?response_type=code&client_id=87654321-
2222-3333-4444-
123456789012&redirect_uri=https://FrontEndWebAppB.sevecek.com&resource=https://bac
kEndSharedWebService.gopas.cz
GET
https://adfs.gopas.cz/adfs/oauth2/authorize?response_type=code&client_id=01010101-
2222-3333-4444-
123456789012&redirect_uri=https://localJavaScriptDummyToken/id&resource=https://back
EndSharedWebService.gopas.cz
2. 3. 2020
106
The authorization grant requests
POST https://adfs.gopas.cz/adfs/oauth2/token
grant_type=authorization_code&client_id=12345678-2222-3333-4444-
123456789012&redirect_uri=https://portal.gopas.cz&code=[code]
POST https://adfs.gopas.cz/adfs/oauth2/token
grant_type=authorization_code&client_id=87654321-2222-3333-4444-
123456789012&redirect_uri=https://backEndSharedWebService&code=[code]
POST https://adfs.gopas.cz/adfs/oauth2/token
grant_type=authorization_code&client_id=01010101-2222-3333-4444-
123456789012&redirect_uri=https://portal.gopas.cz&code=[code]