Minule jsme se podívali - z obecnějšího pohledu - jak SAML funguje pro autentikaci aplikace. Kromě toho, že byste měli znovu zkouknout ty pěkné barevné diagramy, zobrazující SSO (Single Sign-On) a SLO (Single Logout), by se vám mohl hodit SAML a ADFS slovníček - od teď už očekávám, že termíny máte našprtané ;-)
Tenhle článek se bude zaměřovat na konfiguraci potřebnou pro to, aby nám SAML autentikace fungovala. V realitě pak tato konfigurace půjde nejčastěji ruku v ruce s implementací, protože abyste získali SP (Service Provider) metadata, budete potřebovat ho mít už funkční (pokud nejste SAML-Superman, který to zvládne nabouchat ručně, nebo externím nástrojem).
Registrace metadat se může provést dvojím způsobem - buď můžeme poskytnou URL, na kterém si IdP/SP metadata sám stáhne při svém startu, nebo (asi častější) metadata poskytneme jako statický soubor. Zde budeme pracovat s druhým případem.
Metadata na ADFS serveru najdeme na následujícím URL:
Federation Metadata je dlouhý, ošklivý XML soubor. Způsob, jak ho poskytnout naší aplikaci je trojí:
Pokud např. soubor FederationMetadata.xml umístíme do adresáře src/main/resource/metadata, můžeme ho načíst následujícím způsobem:
Pokud potřebujete trochu víc (Spring) kontextu, může se podívat do kompletní Spring SAML konfigurace:
Situace je samozřejmě trochu složitější, takže pokud jste netrpělivý, nebo vám chybí potřebné Spring beany, nahlídněte do zmiňované SecurityConfiguration.java.
Ještě než si metadata vygenerujete a stáhnete z daného URL, jedno důležité upozornění! Při nesplnění následujících podmínek vám SAML před ADFS nebude fungovat.
Tenhle článek se bude zaměřovat na konfiguraci potřebnou pro to, aby nám SAML autentikace fungovala. V realitě pak tato konfigurace půjde nejčastěji ruku v ruce s implementací, protože abyste získali SP (Service Provider) metadata, budete potřebovat ho mít už funkční (pokud nejste SAML-Superman, který to zvládne nabouchat ručně, nebo externím nástrojem).
Registrace metadat
Aby nám SAML fungoval, musíme nejdřív vzájemně zaregistrovat jednotlivé IdP (Identity Providery) a SP (Service Providery). Jak jsme si říkali v minlém díle, vztah IdP - SP může být M:N, nicméně pro zbytek článku (a i v tom následujícím) budeme uvažovat jenom vztah 1:1, tedy náš SP (aplikace) se autentikuje vůči jednomu IdP.Registrace metadat se může provést dvojím způsobem - buď můžeme poskytnou URL, na kterém si IdP/SP metadata sám stáhne při svém startu, nebo (asi častější) metadata poskytneme jako statický soubor. Zde budeme pracovat s druhým případem.
Registrace (ADFS) Federation metadat
Registrace Federation Metadat je jednoduchá - stáhneme XML soubor z daného URL a protože pro implementaci SP používáme Spring Security SAML, poskytneme ho jako resource pro MetadataProvider.Metadata na ADFS serveru najdeme na následujícím URL:
Federation Metadata je dlouhý, ošklivý XML soubor. Způsob, jak ho poskytnout naší aplikaci je trojí:
- dát ho na classpath a načíst třídou ClasspathResource
- dát ho na file systém a načíst třídou FilesystemResource
- načíst ho přímo z ADFS třídou HttpResource
Pokud např. soubor FederationMetadata.xml umístíme do adresáře src/main/resource/metadata, můžeme ho načíst následujícím způsobem:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Bean | |
public MetadataProvider metadataProvider() | |
throws ResourceException, MetadataProviderException { | |
ClasspathResource resource = | |
new ClasspathResource("/metadata/FederationMetadata.xml"); | |
ResourceBackedMetadataProvider provider = new | |
ResourceBackedMetadataProvider(timer, resource); | |
provider.setParserPool(parserPool()); | |
return provider; | |
} |
Pokud potřebujete trochu víc (Spring) kontextu, může se podívat do kompletní Spring SAML konfigurace:
Registrace (Spring) SAML metadat
Registraci SAML metadat na ADFS si rozdělíme do dvou kroků:- Získání metadat z aplikace.
- Registraci metadat na ADFS.
Generování SAML metadat (z aplikace)
Tady přichází ke slovu, co jsem předesílal - abyste byli schopný si vygenerovat SAML metadata, budete potřebovat mít Spring SAML aspoň částečně naimplementovaný. O generování metadat se stará Springovský filtr MetadataGeneratorFilter.
Generování metadat out-of-the-box funguje dobře (a s ADFS ho rozchodíte). Pokud chcete, nebo musíte metadata upravit, tohle je to správné místo. Například specifické (SP) Entity ID se dá nastavit tímto způsobem:
Filter pak necháme naslouchat na určitém URL endpointu, kde nám bude metadata poslušně generovat:
Generování metadat out-of-the-box funguje dobře (a s ADFS ho rozchodíte). Pokud chcete, nebo musíte metadata upravit, tohle je to správné místo. Například specifické (SP) Entity ID se dá nastavit tímto způsobem:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Bean | |
public MetadataGeneratorFilter metadataGeneratorFilter() { | |
MetadataGenerator metadataGenerator = new MetadataGenerator(); | |
metadataGenerator.setEntityId("cz:swsamuraj:wicket:spring:sp"); | |
metadataGenerator.setKeyManager(keyManager()); | |
return new MetadataGeneratorFilter(metadataGenerator); | |
} |
Filter pak necháme naslouchat na určitém URL endpointu, kde nám bude metadata poslušně generovat:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Bean | |
public FilterChainProxy samlFilter() throws Exception { | |
List<SecurityFilterChain> chains = new ArrayList<SecurityFilterChain>(); | |
chains.add(new DefaultSecurityFilterChain( | |
new AntPathRequestMatcher("/saml/metadata/**"), metadataDisplayFilter())); | |
return new FilterChainProxy(chains); | |
} |
Situace je samozřejmě trochu složitější, takže pokud jste netrpělivý, nebo vám chybí potřebné Spring beany, nahlídněte do zmiňované SecurityConfiguration.java.
Ještě než si metadata vygenerujete a stáhnete z daného URL, jedno důležité upozornění! Při nesplnění následujících podmínek vám SAML před ADFS nebude fungovat.
- Na URL musíte přistoupit přes HTTPS (a mít tedy odpovídajícím způsobem nakonfigurovaný aplikační server/servlet kontejner).
- Na URL musíte přistoupit přes hostname nebo IP adresu, které jsou z IdP (ADFS) viditelné. (Takže ne https://localhost.)
Registrace metadat na ADFS
Teď se magicky přenesema na ADFS server (typicky přes Remote Desktop), kam si zkopírujeme vygeneraovaný SAML metadata soubor. Spring ho defaultně nazývá spring_saml_metadata.xml, nicméně na jméně nezáleží.
V AD FS Management konzoli nás bude zajímat jediná věc - položka Relying Party Trust, kde metadata našeho SP zaregistrujeme, resp. naimportujeme.
Import metadat se provádí pomocí wizardu (jak jinak ve Windows). Je to jednoduché a přímočaré: zadáme import ze souboru a pak už se jen doklikáme nakonec:
V závěrečném shrnutí je dobré si zkontrolovat, že v sekci Endpoints jsou splněny dvě výše uvedené podmínky (HTTPS a hostname/IP adresa):
ADFS defaultně očekává, že hash algoritmus použitý při podepisování SAML zpráv bude SHA-256. Bohužel, Spring SAML posílá out-of-the-box SHA-1. Máte tedy dvě možnosti:
Nastavení Secure hash algorithm najdete po rozkliknutí Properties na záložce Advanced (je potřeba to udělat dodatečně - při importu metadat je tato volba nefunkční):
Pokud si to na obou stranách nesladíte, budete na straně Springu dostávat nic neříkající výjimku:
V příštím, závěrečném díle, se podíváme, jak nabastlit zbytek Springovských věcí - můžete se těšit na Java konfiguraci (což je zatím vzácnost, protože Reference Documentation stále jede na XML) a samozřejmě pofrčíme na aktuálním Spring 5 (Cože?!? Vy jedete ještě na čtyřce?! No, nekecej 8-)
V AD FS Management konzoli nás bude zajímat jediná věc - položka Relying Party Trust, kde metadata našeho SP zaregistrujeme, resp. naimportujeme.
![]() |
AD FS Management konzole |
Import metadat se provádí pomocí wizardu (jak jinak ve Windows). Je to jednoduché a přímočaré: zadáme import ze souboru a pak už se jen doklikáme nakonec:
![]() |
Import SP metadat ze souboru |
V závěrečném shrnutí je dobré si zkontrolovat, že v sekci Endpoints jsou splněny dvě výše uvedené podmínky (HTTPS a hostname/IP adresa):
![]() |
Kontrolní shrnutí SP endpointů |
ADFS defaultně očekává, že hash algoritmus použitý při podepisování SAML zpráv bude SHA-256. Bohužel, Spring SAML posílá out-of-the-box SHA-1. Máte tedy dvě možnosti:
- Upravit Spring SAML, aby používal SHA-256 (jak to ohackovat vám prozradím příště),
- nebo říct ADFS, aby očekávalo SHA-1.
Nastavení Secure hash algorithm najdete po rozkliknutí Properties na záložce Advanced (je potřeba to udělat dodatečně - při importu metadat je tato volba nefunkční):
![]() |
Nastavení Secure hash algorithm |
Pokud si to na obou stranách nesladíte, budete na straně Springu dostávat nic neříkající výjimku:
2018-01-17 12:15:01 DEBUG org.springframework.security.saml.SAMLProcessingFilter - Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:100) ~[spring-security-saml2-core-1.0.3.RELEASE.jar:1.0.3.RELEASE] at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.0.0.RELEASE.jar:5.0.0.RELEASE] Caused by: org.opensaml.common.SAMLException: Response has invalid status code urn:oasis:names:tc:SAML:2.0:status:Responder, status message is null at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:113) ~[spring-security-saml2-core-1.0.3.RELEASE.jar:1.0.3.RELEASE] at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:87) ~[spring-security-saml2-core-1.0.3.RELEASE.jar:1.0.3.RELEASE]A na straně ADFS nápomocnější:
Microsoft.IdentityServer.Protocols.Saml.SamlProtocolSignatureAlgorithmMismatchException: MSIS7093: The message is not signed with expected signature algorithm. Message is signed with signature algorithm http://www.w3.org/2000/09/xmldsig#rsa-sha1. Expected signature algorithm http://www.w3.org/2001/04/xmldsig-more#rsa-sha256.Takže, prozatím SHA-1. "Dvě stě padesát šestka" bude příště ;-)
Claim Rules
Poslední věc, kterou zbývá nastavit je mapování claims na assertions. Na naší nově vytvořené Relying Party Trust dáme Edit Claim Rules... a přidáme následující pravidlo, které nám z Active Directory vytáhne Name ID a doménové skupiny daného uživatele:![]() |
Editace Claim Rules |
To be continued...
Tak a máme hotovo! Teda konfiguraci. Ovšem, jak už jsem naznačoval, v tento moment už stejně většinou máte hotovou i zbývající implementaci, takže pokud jsme nic neopomněli, mělo by nám fungovat jak SSO, tak SLO, přesně podlě těch krásných diagramů z minulého dílu.V příštím, závěrečném díle, se podíváme, jak nabastlit zbytek Springovských věcí - můžete se těšit na Java konfiguraci (což je zatím vzácnost, protože Reference Documentation stále jede na XML) a samozřejmě pofrčíme na aktuálním Spring 5 (Cože?!? Vy jedete ještě na čtyřce?! No, nekecej 8-)
Žádné komentáře:
Okomentovat
Poznámka: Komentáře mohou přidávat pouze členové tohoto blogu.