AIS Springboot + SAML2 Authentication
Tip:
If your application requires only HawkID based authentication, it is recommended to use autoconfigure-auth-oidc instead.
Description
autoconfigure-auth-saml2 is a library designed to help its consumers use the SAML2 SSO for their application. It uses Spring Security which provides comprehensive SAML2 support.[4]
This module is compatible with ais-nuxt module.
Acronyms
This section provides definitions for the acronyms used throughout this document.
- SSO[3]:
- Single sign-on (SSO) is a technology which combines several different application login screens into one.
- With SSO, a user only has to enter their login credentials (hawk-id, password) one time on a single page to access all of their SaaS applications.
- SAML1,2:
- Security Assertion Markup Language (SAML), is a standardized way to tell external applications and services that a user is who they say they are.
- SAML makes SSO technology possible by providing a way to authenticate a user once and then communicate that authentication to multiple applications.
- SAML Assertion:
A special token format containing the result of an authentication event plus any accompanying information about the user who authenticated. - Shibboleth: An open-source software consortium that makes a variety of packages to handle the different steps of a SAML login flow. People often use the word Shibboleth interchangeably with SAML itself, or any of the packages that they provide.
- Relying Party (RP) or Service Provider (SP):
NOTE: SP and RP are synonymous and this is what your application will be.
An application that receives and parses identity information sent to it by an Identity Provider in a SAML assertion. Typically installed as a piece of middleware in front of any application you'd like to integrate with HawkID authentication. - Identity Provider (IdP) or Asserting Party (AP):
NOTE: IdP and AP are synonymous.
An application that handles authenticating users after a request from a Service Provider by validating their username and password, gathering identity information, and sending the result back in a SAML assertion. Managed on our campus by ITS - IAM team and other institution's IAM team. More info on this below. - EntityID:
A formal name for an SP, typically based on the application's URL for ease of recognition and to avoid namespace conflicts, but theoretically it could be any unused string. Once chosen, an EntityID should never be changed.
Flow
Prerequisites
1. Include this library
//gradle example
repositories {
...
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
}
dependencies {
...
implementation 'uiowa.springboot:autoconfigure-web'
implementation 'uiowa.springboot:autoconfigure-auth-saml2'
}2. Generate SHA256 base certificate
- If you don’t have OpenSSL installed, install it via homebrew or download and install it first.shell
brew install openssl - Run the command given below to generate SHA256 Keypair (feel free to use a different filenames).shell
openssl req -x509 -sha256 -days 3650 -nodes -newkey rsa:2048 -keyout bor-datasets-sp.key -out bor-datasets-sp.certNOTE:
bor-datasets-sp.cert(certificate file or content) will be shared to the IdPs. - Place certificates to your application's resources folder.
Feel free to customize the folder structure, just remember to update the application properties accordingly. All the examples list below would follow the below structure.bor-datasets-service └── src └── main └── resources ├── saml │ ├── metadata │ │ └── ... │ ├── bor-datasets-sp.cert │ └── bor-datasets-sp.key └── ...
3. Register Application with IdP(s)
A crucial step to using this library is to register your application with identity providers (depending on how many your application supports).
Email the ITS IAM team (its-iam@uiowa.edu) with the below information, so that they can register your application within the identity provider.
NOTE: Below is just an example, and not a set template. Please update/replace as per your requirements.
Generate Application's metadata files
- Start your backend server (assuming it's running on port 8008)
- In your browser, enter http://localhost:8008/bor-datasets/saml2/service-provider-metadata/uiowa to download the SP metadata file for your local application.
- Create copies of this metadata file per environment you plan to support. Edit each environment file, and update all the local url with environment specific URL. eg: Replace http://localhost:8008 -> https://bor-datasets-dev.ais.its.uiowa.edu
- We will share/attach all these file with the IDP when registering our app.
Applications to support
| Environment | Application URL (includes base url) |
|---|---|
| LOCAL | http://localhost:8008/bor-datasets |
| DEV | https://bor-datasets-dev.ais.its.uiowa.edu/bor-datasets |
| TEST | https://bor-datasets-test.ais.its.uiowa.edu/bor-datasets |
| PROD | https://bor-datasets.ais.its.uiowa.edu/bor-datasets |
Base Endpoints (where uiowa is the registration-id, and <APP_URL> will be the application URL from above table)
| Type | Endpoint |
|---|---|
| EntityID | <APP_URL>/saml2/service-provider-metadata/uiowa |
| Assertion Consumer Service (ACS) URL | <APP_URL>/login/saml2/sso/uiowa |
| Single Logout Service (SLO) URL | <APP_URL>/logout/saml2/slo |
Attributes required by the application
- First Name
- Last Name
Add any additional attributes required by your application.
IAM Team's response
Once configured, the IAM team will reply back with the
IdP metadata files(.xml), and attributes mapping.
We will need to add these later to our application configuration/properties.
Register Application with other IdP(s)
This will be very similar to the above request, with change just to the registration-id.
| University | Contact Details |
|---|---|
| University of Iowa (UIOWA) | its-iam@uiowa.edu |
| Iowa State University (ISU) | shibboleth@iastate.edu, prabathd@iastate.edu |
| University of Northern Iowa (UNI) | shibboleth@uni.edu, jeff.chapin@uni.edu |
Usage
Configure Application
Please refer to the applications implementing this library for additional examples on how to configure the application.
Add SAML2 IdP Metadata Files
Place files (provided by the IAM team) to your application's resources folder.
Feel free to customize the folder structure, just remember to update the application properties accordingly. All the examples list below would follow the below structure.bor-datasets-service └── src └── main └── resources ├── saml │ └── metadata │ ├── uiowa_idp_prod_metadata.xml │ └── uiowa_idp_test_metadata.xml ├── application.yml ├── application.dev.yml ├── application.prod.yml └── application.test.ymlUpdate SAML2 Properties
Common Properties
yaml#### application.yml #### common-properties: credentials: &common-credentials - private-key-location: classpath:saml/bor-datasets-sp.key certificate-location: classpath:saml/bor-datasets-sp.cert relying-party-registration: &common-relying-party-registration signing.credentials: *common-credentials decryption.credentials: *common-credentials singlelogout: binding: POST url: "{baseUrl}/logout/saml2/slo" spring: security: saml2: relyingparty: registration: uiowa: << : *common-relying-party-registration assertingparty: metadata-uri: classpath:saml/metadata/uiowa_idp_test_metadata.xml singlelogout: binding: POST isu: # Assuming that that app is registered by ISUs IdP <<: *common-relying-party-registration assertingparty: metadata-uri: classpath:saml/metadata/isu_idp_test_metadata.xml singlelogout: binding: POST #... other registered IdPsOR if you prefer
.properties(NOTE - below properties are not tested)properties#### application.properties ### spring.security.saml2.relyingparty.registration.uiowa.signing.credentials[0].certificate-location=classpath:saml/bor-datasets-sp.cert spring.security.saml2.relyingparty.registration.uiowa.signing.credentials[0].private-key-location=classpath:saml/bor-datasets-sp.key spring.security.saml2.relyingparty.registration.uiowa.decryption.credentials[0].private-key-location=classpath:saml/bor-datasets-sp.key spring.security.saml2.relyingparty.registration.uiowa.decryption.credentials[0].certificate-location=classpath:saml/bor-datasets-sp.cert spring.security.saml2.relyingparty.registration.uiowa.singlelogout.binding=REDIRECT spring.security.saml2.relyingparty.registration.uiowa.assertingparty.metadata-uri= classpath:saml/metadata/uiowa_idp_test_metadata.xml spring.security.saml2.relyingparty.registration.uiowa.assertingparty.singlelogout.binding=REDIRECT # Assuming that that app is registered by ISUs IdP spring.security.saml2.relyingparty.registration.isu.signing.credentials[0].certificate-location=classpath:saml/bor-datasets-sp.cert spring.security.saml2.relyingparty.registration.isu.signing.credentials[0].private-key-location=classpath:saml/bor-datasets-sp.key spring.security.saml2.relyingparty.registration.isu.decryption.credentials[0].private-key-location=classpath:saml/bor-datasets-sp.key spring.security.saml2.relyingparty.registration.isu.decryption.credentials[0].certificate-location=classpath:saml/bor-datasets-sp.cert spring.security.saml2.relyingparty.registration.isu.singlelogout.binding=REDIRECT spring.security.saml2.relyingparty.registration.isu.assertingparty.metadata-uri= classpath:saml/metadata/isu_idp_test_metadata.xml spring.security.saml2.relyingparty.registration.isu.assertingparty.singlelogout.binding=REDIRECT #... other registered IdPsDEV Properties
yaml#### application.dev.yml #### # Using TEST's entity-id as we have configured LOCAL and DEVs ACS and SLO endpoints in TEST's service provider. spring: security: saml2: relyingparty: registration: uiowa: entity-id: https://bor-datasets-test.ais.its.uiowa.edu/bor-datasets/saml2/service-provider-metadata/uiowaOR if you prefer
.propertiesproperties#### application.dev.properties ### # Using TEST's entity-id as we have configured LOCAL and DEVs ACS and SLO endpoints in TEST's service provider. spring.security.saml2.relyingparty.registration.uiowa.entity-id=https://bor-datasets-test.ais.its.uiowa.edu/bor-datasets/saml2/service-provider-metadata/uiowaPROD Properties
yaml#### application.prod.yml #### spring: security: saml2: relyingparty: registration: uiowa: assertingparty: metadata-uri: classpath:saml/metadata/uiowa_idp_prod_metadata.xmlOR if you prefer
.propertiesproperties#### application.prod.properties ### spring.security.saml2.relyingparty.registration.uiowa.assertingparty.metadata-uri=classpath:saml/metadata/uiowa_idp_prod_metadata.xmlUpdate SAML2 Attributes
With reference to the registered attributes, we need to map these so that the library is able to map them to the AisUser (which can then be use for authentication).
yamluiowa: ais: auth: saml2: attribute-keys: uiowa: # registration-id #Key: Value(provided by IAM team) universityId: "urn:oid:8.0.008.80000008.800.0.8"NOTE:
email,hawkid,lastname, andfirstnameare registered by default and need not be added here. Refer to Saml2AuthProperties.getDefaultAttributeKeys to see the default attributesImplement AisUserDetailsService Interface
java@Service public class UserDetailService implements AisUserDetailService { @Override @Transactional(readonly = true) public AisUser getUser(AisUser aisUser) throws AisUserNotFoundException { String email = aisUser.email(); /* * Add your logic here. * eg: * - Use aisUser to check if it's a valid application user * - Get roles from the backend, etc. */ try { return new AisUser.Builder() .fromAisUser(aisUser) .roles(Set.of("ADMIN_ROLE")) .build(); } catch (Exception ex) { throw new AisUserNotFoundException(ex); } } }Implement OnLogin Interface (Optional)
java@Service public class OnLoginService implements OnLogin { @Override public void execute(AisUser aisUser, HttpServletRequest httpServletRequest) throws Exception { // Logic for post successful login. // Update user's last login, etc... } }
Hopefully after this step you should be able to start your application and perform SAML2 authentication.
In case of any issues/concerns please feel free to reach out to our slack support channel: #tool-ais-springboot.