Vous êtes sur la page 1sur 99

27. 5.

2019

ADFS and Web Application


Proxy
Ing. Ondřej Ševeček | GOPAS a.s. |
MCSM:Directory2012 | MCM:Directory2008 | MVP:Enterprise Security | CEH |
CHFI | CISA |
ondrej@sevecek.com | www.sevecek.com |

GOPAS: info@gopas,cz | www.gopas.cz | www.facebook.com/P.S.GOPAS

ADFS intranet scenarios

1
27. 5. 2019

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
 Web services easy handling of tokens
• no worry about security
• just a signed piece of XML/JSON

2
27. 5. 2019

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 passive
clients
• 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”

3
27. 5. 2019

ADFS version history


Version OS Notes Support

included
ADFS 1.0 Windows 2003 R2 SAML 1.1
runs in IIS

Windows 2008 included


ADFS 1.1 SAM 1.1 tokens
Windows 2008 R2 runs in IIS

Windows 2008 download


ADFS 2.0 SAML 2.0 tokens
Windows 2008 R2 runs in IIS

included
ADFS 2.1 Windows 2012 device registration
runs in IIS

included
direct hosting on HTTP.SYS multifactor auth
ADFS 3.0 Windows 2012 R2 TLS SNI support password change
PowerShell only config (plus HTML/Javascript) /adfs/probe
OAuth implicit grant
admin delegation
own certification authority for device registration
http to https redirection with WAP Azure MFA
ADFS 4.0 Windows 2016
http publishing with WAP Microsoft Passport
OAuth full
OAuth and HTTP basic authentication with WAP

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

4
27. 5. 2019

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

5
27. 5. 2019

ADFS installation #2

ADFS farm behind a load balancer with a


common SQL server

Browser
Browser ADFS1
client
client
https://adfs.gopas.cz

Load
Balancer
SQL

GUI
GUI ADFS2
client
client

6
27. 5. 2019

ADFS farm behind a load balancer with a


common SQL server

same
cert
TCP
443
Browser
Browser ADFS1
client
client
https://adfs.gopas.cz

Load
Balancer SQL

GUI
GUI ADFS2
client
client

same
cert

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

primary
Browser
Browser ADFS1 member
client
client
https://adfs.gopas.cz
WID
Load
Balancer
replication

GUI
GUI ADFS2
client
client ADFSn
WID
WID

7
27. 5. 2019

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

8
27. 5. 2019

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))

9
27. 5. 2019

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

10
27. 5. 2019

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

11
27. 5. 2019

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+)

12
27. 5. 2019

ADFS installation #11


 SsoLifetime
• lifetime of the MSISAuth session cookie by default
 KsmiLifetimeMins
• lifetime of the MSISAuth persistent cookie if when KMSI enabled

ADFS installation #12

13
27. 5. 2019

ADFS installation #13

ADFS installation #14


 do not forget about certauth.adfs.gopas.cz

14
27. 5. 2019

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

15
27. 5. 2019

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

16
27. 5. 2019

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

17
27. 5. 2019

ADFS installation #21

ADFS installation #22

18
27. 5. 2019

ADFS installation #23

ADFS installation #24


 Transport and Mixed endpoints use HTTPS
 SOAP Message security does not require HTTPS

19
27. 5. 2019

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

20
27. 5. 2019

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

21
27. 5. 2019

ADFS installation #29


Device Registration (10) aka Workplace Join (8.1)

 runas Enterprise Admins member


 Initialize-ADDeviceRegistration -ServiceAccount
gps\gsvc-adfs$
 DNS CNAME enterpriseregistration.UserUPNsuffix
• or A (SPN not necessary)

 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,D
C=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

22
27. 5. 2019

Simple ADFS terminology

Passive client

DC
Browser
GPS WIA (Kerberos) Client
gopas.virtual
Basic

Forms

Request Incoming claims GUI


Client
ADFS
Active client
Outgoing claims

"Cookie" or "token"
https://adfs.gopas.cz

SQL Attribute stores

LDAP

ADFS internal testing

DC
Browser
GPS Client
gopas.virtual

WIA (Kerberos)
GUI
Basic
Client

Forms

TLS Certificate
ADFS
https://adfs.gopas.cz

23
27. 5. 2019

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

24
27. 5. 2019

Extract ADFS token signing certificate from XML

Quick ASCII, Base64 and URL reference

%3D = %26 & %2F / %3F ?


%3A : %2B + %3C < %20 space

[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( ' ')))))

25
27. 5. 2019

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

Passive client authentication


Service Provider
Identity Provider
Relying Party
Claims Provider

Web
Web App
Web ADFS
App
Web
App
App

1
GET
https://finance

Passive
Client

26
27. 5. 2019

Passive client authentication


Service Provider
Identity Provider
Relying Party
Claims Provider

Web
Web App
Web ADFS
App
Web
App
App

1
GET
https://finance

2
302
https://adfs.gopas.cz

Passive
Client

Passive client authentication


Service Provider
Identity Provider
Relying Party
Claims Provider

Web
Web App
Web ADFS
App
Web
App
App

3
GET authenticate
https://adfs.gopas.cz

Passive
Client

27
27. 5. 2019

Passive client authentication


Service Provider
Identity Provider
Relying Party
Claims Provider

Web
Web App
Web ADFS
App
Web
App
App

XML
claims token

POST Submit JavaScript


https://finance
4
COOKIE: MSISAuth: adfs.gopas.cz

COOKIE: MSISSignOut: adfs.gopas.cz


finance RP
Passive portal RP
Client office365 RP

Passive client authentication


Service Provider
Identity Provider
Relying Party
Claims Provider

Web
Web App
Web ADFS
App
Web
App
App
5
POST
https://finance

XML
claims token
XML
claims token

POST Submit JavaScript


https://finance
4
COOKIE: MSISAuth: adfs.gopas.cz

COOKIE: MSISSignOut: adfs.gopas.cz


finance RP
Passive portal RP
Client office365 RP

28
27. 5. 2019

Passive client authentication


Service Provider
Identity Provider
Relying Party
Claims Provider

Web
Web App
Web ADFS
App
Web
App
App
5
POST
https://finance

XML
claims token
XML
6 claims token
OK
https://finance POST Submit JavaScript
https://finance
COOKIE: FedAuth: finance 4
COOKIE: MSISAuth: adfs.gopas.cz

COOKIE: MSISSignOut: adfs.gopas.cz


finance RP
Passive portal RP
Client office365 RP

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

29
27. 5. 2019

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

30
27. 5. 2019

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")

31
27. 5. 2019

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!!

Token signature only


Service Provider
Identity Provider
Relying Party
Claims Provider
signing cert

Web
priv
Web App
Web ADFS
App
Web
App
App
5
POST
https://finance

XML signed
claims token
XML
claims token
POST Submit JavaScript
https://finance
4

Passive can read


Client

32
27. 5. 2019

Token signature and encryption


Service Provider
Identity Provider
Relying Party
Claims Provider
signing cert

Web
priv
Web App encryption cert
Web ADFS
App
Web
App pub

App
5
POST
https://finance
encrypted

XML signed
claims token
XML
claims token
POST Submit JavaScript
https://finance
4

Passive cannot read


Client

Standards
Name What How Notes

WIF (Windows
transport
WS-Federation passive clients Identity
302/POST redirects
Foundation)

WS-Trust transport active SOAP clients

SAML-P, SAMLP, SAML transport passive client ADFS 3.0


protocol 302/POST redirects active SOAP clients no NETFX support

used by WS-Federation
SAML 1.0 XML token format ADFS 1.0
urn:oasis:names:tc:saml:1.0:assertion

used by WS-Federation
SAML 1.1 XML token format ADFS 1.1
urn:oasis:names:tc:saml:1.0:assertion

used by SAMLP
SAML 2.0 XML token format ADFS 2.0
urn:oasis:names:tc:saml:2.0:assertion

transport + token active SOAP clients


OAuth ADFS 3.0
format tokens JWT (JSON Web Token)

33
27. 5. 2019

Testing ADFS from browser (authentication)


 https://adfs.gopas.cz/adfs/ls?SAMLRequest=deflatedBase
64request
• 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_typ
e=code&client_id=11111111-2222-3333-4444-
123456789012&redirect_uri=https://portal.gopas.cz&reso
urce=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://a
dfs.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 ...

34
27. 5. 2019

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%2Fuu7uSVNf2sB7Cu
33CjwEpsGPXWoITUfHBW3CKDIFVHRKEBvbr3R2kkwR674JrXMvPLJcdigh
9MM5ytt1U%2FK2QhayTOhVyqVOR1SoVC73MRJrVOebzutASo5RowK2loG
yoeJrITCRSzJJnOQe5gFn%2BytkLeoq5kZ4knK1%2F59w4S0OHfo%2F%2B
0zQx5IDHikfF6vqKsXJsDKd4vxp7azygV6MRdqbxjpwOD7Y1FsvpufbP3MN9
XHK7eXStab7YrfOdCpdvMCLmIPRJCv3YmwLawKcx9mfM%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>

35
27. 5. 2019

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 for Office 2013


 Install all updates!!!
 Enable on client
HKCU\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)
• if non enabled, Outlook uses WS-Federation redirection with web page GUI
 plus can perform MFA
 Cleaning the cache
• delete the whole Identity key
Remove-Item HKCU:\Software\Microsoft\Office\15.0\Common\Identity -Recurse

36
27. 5. 2019

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

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

37
27. 5. 2019

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

Testing ADFS from browser with Fiddler


 Get-AdfsProperties
 by default requires extended protection for WIA
 Set-AdfsProperties -ExtendedProtectionTokenCheck
None

38
27. 5. 2019

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
MSAuthHost/1.0/In-Domain MSIE 6.0
Trident/7.0 MSIE 7.0
MSIPC MSIE 8.0
Windows Rights Management Client 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

39
27. 5. 2019

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

40
27. 5. 2019

Initialize Azure MFA on Windows 2016


$tenant = 'sevecekeu201710.onmicrosoft.com'
$admin = "admin@$tenant"

# 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

Connect-MsolService -Cred (Get-Credential $admin)

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 Policies
Get-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");'

41
27. 5. 2019

Disable double MFA pop-ups on Azure accounts which


require MFA
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");

ADFS motivation and GUI applications

ADFS
web
web service
webservice
service

POST Redirect https://webservice


parameters
POST body 302 Redirect https://webservice sign-in URL
SOAP response
SOAP reply authenticate
throught the
token with app
limited lifetime

HTTP based or SOAP based

untrusted
sandboxed
app

user device

42
27. 5. 2019

ADFS motivation and UWA applications

ADFS
web
web service
web
service
service

sign-in URL

authenticate
securelly

untrusted
trusted
sandboxed
browser
app sign-in URL

user device

ADFS motivation and UWA applications

ADFS
web https://finance
web service
web
service
service

token with
limited lifetime sign-in URL

authenticate
POST Redirect ms-app://localAppID
securelly
302 Redirect ms-app://localAppID

query
parameters
untrusted
trusted
sandboxed
browser
app sign-in URL

user device

43
27. 5. 2019

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

44
27. 5. 2019

Claim rules (basics)


# general format to add outgoing claim (no OR operator exists)
# == equals, =~ 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 );

45
27. 5. 2019

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"])

46
27. 5. 2019

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(...)

47
27. 5. 2019

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
);

48
27. 5. 2019

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

49
27. 5. 2019

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

50
27. 5. 2019

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?

51
27. 5. 2019

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

 Custom themes
• New-AdfsWebTheme -Name myOwn -SourceName default
• Set-AdfsWebConfig -ActiveTheme

ADFS home real discovery (HRD) pages


customizations
 Add UPN suffixes for easier startup
• Set-AdfsClaimsProviderTrust -TargetName thePartner -
OrganizationalAccountSuffix 'sevecek.com'

 Disable HRD for intranet locations


• Set-AdfsProperties -IntranetUseLocalClaimsProvider $true

52
27. 5. 2019

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

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
)

53
27. 5. 2019

ADFS extranet scenarios with


WAP reverse HTTPS proxy

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

54
27. 5. 2019

Principal scenario – claims aware web applications


(internal HTTP or HTTPS)

TLS Certificate
https://finance.gopas.virtual
https://finance.gopas.cz
https://finance TLS Certificate
Web Reverse
Web
Server
Web HTTPS
Server
Server Proxy Browser
Client
TLS Certificate
TLS Certificate

GUI
https://adfs.gopas.cz Client
Reverse
HTTPS
DC ADFS Proxy
DC
TLS Certificate
GPS
gopas.virtual

Principal scenario – claims aware web applications


(internal HTTP or HTTPS)

TLS Certificate
https://finance.gopas.virtual

https://finance TLS Certificate


Web https://finance.gopas.cz
Web
Server
Web TLS Certificate
Server
Server Browser
Client
TLS Certificate

WAP
GUI
https://adfs.gopas.cz
Client
TLS Certificate

DC ADFS
DC

GPS
gopas.virtual

55
27. 5. 2019

Principal scenario - Basic authentication web applications


(internal HTTP or HTTPS)

http://portal
Web
Web
Server
Web Browser
Server https://portal.gopas.cz
Server Client
basic
Reverse
HTTPS
Proxy basic

GUI
TLS Certificate
basic Client

ADFS
DC
DC

GPS
gopas.virtual

Principal scenario - Windows authentication web


applications (internal HTTP or HTTPS)
WAP as domain member

http://portal
Web
Web
Server
Web Browser
Server https://portal.gopas.cz
Server Client
Kerberos
Reverse
HTTPS
Proxy full ADFS

GUI
TLS Certificate
Client

ADFS
DC
DC

GPS
gopas.virtual

56
27. 5. 2019

Principal scenario - Windows authentication web


applications (SharePoint, Exchange, AAM)

http://intranet
Web
Web
Server
Web
Server https://intranet.gopas.cz Browser
Server Client
Reverse
HTTPS
Proxy
TLS Certificate GUI
Client

DC
DC

GPS
gopas.virtual

Principal scenario – Windows/claims web applications


(no AAM necessary)

TLS Certificate

https://sp.gopas.cz TLS Certificate


Web
Web
Server
Web
Server https://sp.gopas.cz Browser
Server Client
Reverse
TLS Certificate HTTPS
Proxy
TLS Certificate GUI
Client

DC
DC

GPS
gopas.virtual

57
27. 5. 2019

Another bit of motivation

 SharePoint
 not everything requires authentication
 HTTP level protocol exploits
• many many many IIS modules to pass

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

58
27. 5. 2019

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)

Publishing ADFS through WAP


can use different TLS certificates for most scenarios
must use the same DNS name

Browser
Client
WAP

TLS Certificate GUI


Client
https://adfs.gopas.cz

ADFS

TLS Certificate
DC
DC https://adfs.gopas.cz

59
27. 5. 2019

Publishing ADFS through WAP


use the same TLS certificate for WAP for TLC client
authentication

Browser
Client
WAP

TLS Certificate GUI


Client
https://adfs.gopas.cz

ADFS

TLS Certificate
DC
DC https://adfs.gopas.cz

WAP installation #1 (WAP as domain member)

 certificate export using ADDS KDS

60
27. 5. 2019

WAP installation #2
Add-WindowsFeature Web-Application-Proxy, RSAT-
RemoteAccess

WAP installation #3
 Admin$ on the primary ADFS server
• after installation HTTPS:443 only (TLS client cert.auth.)

61
27. 5. 2019

WAP installation #4

 Note: will use Kerberos even for SMB


• SPN host/adfs.gopas.cz

WAP installation #5

62
27. 5. 2019

WAP installation #6 (on ADFS server)

WAP installation #7 (WAP own client certificate)


5 (2012 R2) or 14 (2016+) days validity

63
27. 5. 2019

WAP to ADFS client authentication


certificates

Browser
Client
WAP WAP
Client
Cert
https://adfs.gopas.cz
TLS Certificate GUI
TLS Certificate
Client
https://adfs.gopas.cz

ADFS

DC
DC

WAP installation #8 (WAP trusted on ADFS server)

64
27. 5. 2019

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

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

65
27. 5. 2019

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)

WAP installation #12


 pass-through benefits?
• updated and terminated TLS/SSL client <-> WAP
• basic HTTP validation and reconstruction
• HTTP to HTTPS redirection

66
27. 5. 2019

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

WAP installation #14

67
27. 5. 2019

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

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

68
27. 5. 2019

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

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"

69
27. 5. 2019

Hidden WAP relying party and EdgeAccessCookie


timeout (default 60 minutes)
 Set-AdfsWebApplicationProxyRelyingPartyTrust -TokenLifetime

WAP installation #15

70
27. 5. 2019

WAP installation #16


 WAP own access policy to limit access to all published web sites

WAP publishing #17 (ADFS loopback detection)

 Set-AdfsProperties -EnableLoopDetection
• cookie MSISLoopbackDetection

71
27. 5. 2019

WAP publishing #16 (testing ADFS loop detection)

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

72
27. 5. 2019

WAP publishing #18 (enable password change page)

 Enable updatepassword endpoint


• https://adfs.gopas.cz/adfs/portal/updatepassword

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)

73
27. 5. 2019

Publishing SharePoint

 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
http://intranet
Web
Server
Web
Server https://sp.gopas.cz Browser
Server Client
Reverse
host header https://sp.gopas.cz HTTPS
Proxy
TLS Certificate GUI
Client

DC
DC

GPS
gopas.virtual

74
27. 5. 2019

Extend web application first (maybe AAM)


for host header web binding

Web
http://intranet
Web
Server
Web
Server https://sp.gopas.cz Browser
Server Client
Reverse
http://sp.gopas.cz HTTPS
https://sp.gopas.cz Proxy
TLS Certificate GUI
Client

DC
DC

GPS
gopas.virtual

WAP for WIA applications with


Kerberos delegation

75
27. 5. 2019

Wait. First make Kerberos work internally

AppPool Kernel Mode Authentication AD Account for Kerberos

Local System
on/off GPS\WFE$
(SYSTEM)

Local Service
on/off no Kerberos
(NT AUTHORITY\Local Service)

Network Service
on/off GPS\WFE$
(NT AUTHORITY\Network Service)

ApplicationPoolIdentity
on/off GPS\WFE$
(IIS APPPOOL\apppool)

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

76
27. 5. 2019

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

Basic
Browser
Windows NTLM Client
Reverse
HTTPS Windows Kerberos
Proxy
Forms/cookie
TLS Certificate GUI
TLS client certificate Client

DC
DC

77
27. 5. 2019

External authentication challenges


External authentication Facts Internal forwarding Notes

plain-text no browser sign-out no


Basic TLS encrypted easy timeout
no SSO non-browser clients

Kerberos constrained complicated


Windows NTLM SSO
delegation sensitive

not possible without Kerberos constrained impossible


Windows Kerberos
direct contact with DC delegation except for KDC Proxy

plain-text
sign-out
no SSO easy
Forms/cookie timeout
session vs. persistent claims SAML token
browser clients
cookie
safe against password
Kerberos constrained only for "partners"
guessing
TLS client certificate delegation can use smart-cards
safe against HTTP
claims SAML token both clients
exploits

Scenario with an authentication server


TLS Certificate

http://portal.gopas.virtual
TLS Certificate
Web
http://portal
Web
Server
Web
Server https://portal.gopas.cz Browser
Server Client

TLS Certificate WAP

TLS Certificate GUI


Client
RADIUS
?

DC
DC

78
27. 5. 2019

Scenario with ADFS authentication server


TLS Certificate

TLS Certificate
Web
https://portal
Web
Server
Web
Server https://portal.gopas.cz Browser
Server Client

TLS Certificate WAP

TLS Certificate GUI


Client

ADFS

TLS Certificate
DC
DC

Publishing simple WIA web application

http://portalWeb
Web
Server
Web
Server https://portal.gopas.cz Browser
Server Client
Kerberos Delegation
WAP

TLS Certificate GUI


https://adfs.gopas.cz
Client

ADFS

TLS Certificate
DC
DC

79
27. 5. 2019

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

80
27. 5. 2019

Enable Kerberos delegation on WAP server account

Third-parties aka claim


providers

81
27. 5. 2019

Claim provider trusts


AD

Our Partner
Web
ADFS ADFS

https://finance

https://finance

Our Partner
client client

Claim provider trusts


AD

Our Partner
Web
ADFS ADFS

https://adfs.gopas.cz

https://adfs.gopas.cz

Our Partner
client client

82
27. 5. 2019

Claim provider trusts


AD

Our Partner
Web
ADFS ADFS

https://adfs.gopas.cz
https://adfs.book-vendors.com

Our Partner
client client

Claim provider trusts


identity
AD provider

Our Partner
Web
ADFS ADFS
outgoing claims

Our Partner
client client

83
27. 5. 2019

Claim provider trusts


identity
AD provider
relying
party
Our Partner
Web
ADFS ADFS

incoming claims outgoing claims

Our Partner
client client

Claim provider trusts


identity
identity AD provider
provider relying
party
Our Partner
Web
ADFS ADFS

outgoing claims incoming claims outgoing claims

Our Partner
client client

84
27. 5. 2019

Claim provider trusts


identity
relying identity AD provider
provider relying
party
party
Our Partner
Web
ADFS ADFS
incoming claims outgoing claims incoming claims outgoing claims

Our Partner
client client

Workplace join aka


Device registration

85
27. 5. 2019

Initialize-ADDeviceRegistration
 requires Enterprise Admins membership

CN=DeviceRegistrationService,CN=Device Registration Services,CN=Device


Registration Configuration,CN=Services,CN=Configuration

86
27. 5. 2019

Enable-AdfsDeviceRegistration

Enable-AdfsDeviceRegistration

Set-AdfsGlobalAuthenticationPolicy -DeviceAuthenticationEnabled
$true

Device registration enabled in ADFS

87
27. 5. 2019

Device Registration - Register domain joined computers as devices

Workplace Join (Windows 8.1)


 Events
• Application and Service Logs
 Microsoft
– Windows
 Workplace Join
 Tasks
• Microsoft
 Windows
– Workplace Join
 autoworkplace.exe join (only with a logged-on user)

 uses local ADFS (user's UPN suffix)


• https://adfs.gopas.cz/EnrollmentServer/DeviceEnrollmentWebService.svc
• https://adfs.gopas.cz/adfs/oauth2/...
• authenticates as user

88
27. 5. 2019

Device Registration (Windows 10)


 always registers into Azure (sync write-back for local ADFS)
• searches AD for serviceConnectionPoint
• 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)

 uses local ADFS (what comes from AAD as redirected)


• https://adfs.gopas.cz/adfs/services/trust/2005/windowstransport
• authenticates as COMPUTER$

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

89
27. 5. 2019

Workplace joined (Win8.1) device object (msDS-Device) and user's


certificate - The first user registers the device

Device registered (Win10) certificates in computer store

90
27. 5. 2019

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

ADFS Certificate Registration Authority


 Set-AdfsCertificateAuthority -EnrollmentAgent -
EnrollmentAgentCertificateTemplate GOPASWHFBEnrollmentAgent -
WindowsHelloCertificateTemplate GOPASWHFBLogon
• the EnrollmentAgent template must have Subject - Supply in the request

 The 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>

91
27. 5. 2019

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

92
27. 5. 2019

More complex motivation •



Too permanent password which cannot be changed easily
Cannot revoke single client
• Password exposed to questionable services
Resource Owner • User may have direct access to the protected resource

Client A
GUI or Browser

pwd Monthly
payment for
electricity

pwd

pwd
pwd

Client B

pwd
Random

Bank web service


Client C payment for train
tickets

Bank DB
Web shop services
pwd

password

Protected Resource

More complex motivation


Resource Owner
Client A

Authorization Grant
GUI or Browser Monthly
payment for
electricity

pwd

Authorization
Server
Authorization Grant

password

Authorization Grant
Client B

Random
Bank web service

Client C payment for train


tickets

Bank DB
Web shop services

Protected Resource

93
27. 5. 2019

More complex motivation


Resource Owner
Client A

Authorization Grant
GUI or Browser Monthly
payment for
electricity

pwd

Authorization
Server Access Token
Authorization Grant

password

Authorization Grant
Client B

Random

Bank web service


Client C payment for train
tickets Access Token

Bank DB
Web shop services

Access Token

Protected Resource

More complex motivation


Resource Owner
Client A
kamil A

Authorization Grant
GUI or Browser Monthly
payment for
electricity

pwd

Authorization
kamil B
Server Access Token
Authorization Grant

password
kamil C
Authorization Grant
Client B

Random
Bank web service

Client C payment for train


tickets Access Token

Bank DB
Web shop services

Access Token

Protected Resource

94
27. 5. 2019

More complex motivation


Resource Owner
Client A
kamil A

Authorization Grant
GUI or Browser Monthly
payment for
electricity

pwd

Authorization
kamil B
Server Access Token
Authorization Grant
A kamil bank
password
kamil C
Authorization Grant
Client B

Random

Bank web service


Client C payment for train
tickets Access Token

Bank DB
Web shop services

Access Token

C kamil bank

Protected Resource

Complex redirection with confidential client

https://adfs.gopas.cz/adfs/oauth2/authorize

authorization
endpoint
resource
owner
ADFS
GUI or
browser app
authentication request GET

web service
client app B

https://FrontEndWebAppB.sevecek.com

Protected
resource server

https://portal.gopas.cz

95
27. 5. 2019

Complex redirection with confidential or public client

https://adfs.gopas.cz/adfs/oauth2/authorize

authorization
endpoint
resource
owner
ADFS
GUI or
browser app
authentication request GET

web service
client app B

https://FrontEndWebAppB.sevecek.com

ms-app://localAppOnTheClientMachine Protected
resource server
https://localJavaScriptDummyToken/id

https://portal.gopas.cz

Complex redirection with confidential or public client

resource authorization / code grant


owner
ADFS
GUI or
browser app
authentication request GET

web service
client app B

https://FrontEndWebAppB.sevecek.com

ms-app://localAppOnTheClientMachine Protected
resource server
https://localJavaScriptDummyToken/id

https://portal.gopas.cz

96
27. 5. 2019

Complex redirection with confidential or public client

resource authorization / code grant


https://adfs.gopas.cz/adfs/oauth2/token
owner
ADFS
GUI or
browser app token
endpoint
authentication request GET

access token request POST

web service
client app B

https://FrontEndWebAppB.sevecek.com

ms-app://localAppOnTheClientMachine Protected
resource server
https://localJavaScriptDummyToken/id

https://portal.gopas.cz

Complex redirection with confidential or public client

resource authorization / code grant


owner
ADFS
GUI or
browser app
authentication request GET

access token request POST

web service
client app B

https://FrontEndWebAppB.sevecek.com access request

ms-app://localAppOnTheClientMachine Protected
resource server
https://localJavaScriptDummyToken/id

https://portal.gopas.cz

97
27. 5. 2019

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

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

98
27. 5. 2019

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]

99

Vous aimerez peut-être aussi