-
Notifications
You must be signed in to change notification settings - Fork 0
SpringSAMLAuth
This is the tricky bit. There are a few points here...
- this is not easy to test without an IdP to hand
- Its not easy to get an IdP working
- If this doesn't work, its hard to tell if its the IdP or sP going wrong.
Code available here: https://github.com/jim-reespotter/SpringBootSAML/tree/BasicSAML
Simple SpringBoot webapp is working
The plan with SAML is that you can pass authentication off to a trusted 3rd party. This should in theory make you webapp simpler because it doesn't have to do very much it terms of authentication at all. SAML is designed to allow users in a directory of some description owned by one organisation access resources from another organisation without too much of the users' data being shared to the resource organisation. To do this the organisations exchange metadata (web endpoints and public keys) so they can verify each other and communicate securely. The 2 endpoints (identity and resource) never contact each other directly - all messages are given to the browser to pass over (generally via 302HTTP messages)
- Add Spring security bits to build.gradle: dependencies:
- spring-security-config
- spring-security-saml2-service-provider (should still run but now present a login page)
(SAMLSecurityConfig.java, application.yml)
- Rename src/main/resources/application.properties to application.yml
- Add a new java class under src/main/java/stuff/things/SpringBootSAML.java
- annotate it @EnableWebSecurity
- extend it with WebSecurityConfigurerAdapter
- add imports (from org.springframework.security.config.annotation.web.configuration)
- add a new method:
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().permitAll();
}
(re-run it, should now present index page again, no login)
We need to generate a public and private key for SAML signing in src/main/resources/credentials/ - change to that folder and run:
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout private.key -out public.cer
(Answer the questions as you will, they make no difference here)
Add the following to application.yml:
spring:
security:
saml2:
relyingparty:
registration:
MySAMLApp:
signing:
credentials:
- private-key-location: "classpath:credentials/private.key"
certificate-location: "classpath:credentials/public.cer"
identityprovider:
metadata-uri: https://samltest.id/saml/idp
Key points here:
- metadata-uri needs to exist - it will pull the metadata from this site on startup On a good day this will still work as an unauthenticated app.
In this step we create a URL from which you can retrieve this sP's metadata (SAMLSecurityConfig.java): Add an autowired attribute to the SAMLSecurityconfig class:
@Autowired
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
Edit the configure method in SAMLSecurityConfig:
protected void configure(HttpSecurity http) throws Exception {
RelyingPartyRegistrationResolver relyingPartyRegistrationResolver =
new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
http
.saml2Login(withDefaults()) // needs import static org.springframework.security.config.Customizer.withDefaults;
.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class)
.antMatcher("/**")
.authorizeRequests()
.anyRequest()
.permitAll();
}
This configures the metadata endpoint at: http://localhost:8080/saml2/service-provider-metadata/MySAMLApp - this url will present you with the XML metadata required by the IdP (Where MySAMLApp will match application.yml relyingparty.registration) restart the applciation - its also useful to debu at this point: gradle bootRun --debug http://localhost:8080 should still take you to your index page, but you can force authentication with: http://localhost:8080/saml2/authenticate/MySAMLApp (which will fail probably)
you now are in a posistion to exchange metadata (actually, the sP has already pulled the IdP's metadata as defined in application.yml when it started up)
- Save the metdata file from http://localhost:8080/saml2/service-provider-metadata/MySAMLApp
- upload it at https://samltest.id/upload.php Now browse to http://localhost:8080/saml2/authenticate/MySAMLApp again - you should get taken to the IdP, login (rick/psych)
Edit the http. stanza in SAMLSecurityConfig.java/configure:
- replace
permitAll()withauthenticated()Restart the SrpingBoot app, browse to http://localhost:8080 - you should be taken to an authentication page, then back to index.html
Next up: