Customizing the SAML Assertion building logic (AuthnContext) in the WSO2 IS server

Lashan Sivaganeshan
2 min readNov 21, 2018

--

The Current SAML response for SAML SSO scenarios in the WSO2 IS server (wso2is-5.2.0) sends the below Authentication Context for Password.

<saml2:AuthnStatement AuthnInstant=”2018–11–03T12:44:45.001Z”>
<saml2:AuthnContext> <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>

Note the AuthnContextClassRef which contains the following value.

urn:oasis:names:tc:SAML:2.0:ac:classes:Password

If there’s a requirement to change the above AuthnContextClassRef to the following value, since there’s no out of the box facility, a customization should be done to the SAML Assertion building logic as explained below.

urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport

The above value is set in the DefaultSAMLAssertionBuilder [1] through the following configuration in the <IS_HOME>/repository/conf/identity/identity.xml file.

<SAMLSSOAssertionBuilder>org.wso2.carbon.identity.sso.saml.builders.assertion.DefaultSAMLAssertionBuilder</SAMLSSOAssertionBuilder>

The above-mentioned SAMLSSOAssertionBuilder can be customized by adding A JAR containing the custom class in the following directory.

<IS_Home>/repository/components/lib

Once the above-mentioned “SAMLSSOAssertionBuilder” configuration is updated to the relevant class and the Identity Server is restarted the updated SAML Assertion building logic will be applied.

The following repository [2] contains a sample class for the above update (CustomSAMLAssertionBuilder).

Note: Following is the default implementation available in the DefaultSAMLAssertionBuilder.

AuthnStatement authStmt = new AuthnStatementBuilder().buildObject();
authStmt.setAuthnInstant(new DateTime());
AuthnContext authContext = new AuthnContextBuilder().buildObject();
AuthnContextClassRef authCtxClassRef = new AuthnContextClassRefBuilder().buildObject();
authCtxClassRef.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX);
authContext.setAuthnContextClassRef(authCtxClassRef);
authStmt.setAuthnContext(authContext);
if (authReqDTO.isDoSingleLogout()) {
authStmt.setSessionIndex(sessionId);
}
samlAssertion.getAuthnStatements().add(authStmt);

The update done on the CustomSAMLAssertionBuilder) [2] is as follows.

AuthnContext authContext = new AuthnContextBuilder().buildObject();
AuthnContextClassRef authCtxClassRef = new AuthnContextClassRefBuilder().buildObject();
authCtxClassRef.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX);

//Changing the AuthnContext for testtenant.com
if (PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain().toString().equalsIgnoreCase("testtenant.com")) {
log.info("Setting AuthnContext to " + AuthnContext.PPT_AUTHN_CTX.toString());
authCtxClassRef.setAuthnContextClassRef(AuthnContext.PPT_AUTHN_CTX);
}

authContext.setAuthnContextClassRef(authCtxClassRef);
authStmt.setAuthnContext(authContext);
if (authReqDTO.isDoSingleLogout()) {
authStmt.setSessionIndex(sessionId);
}
samlAssertion.getAuthnStatements().add(authStmt);

In the above example, “testtenant.com” (which maps to the tenant domain which is supposed to receive the customized AuthnContext) is hardcoded. And it should be possible to improve this by using an external config file to be read while building SAML responses containing tenant domains which require such an update, rather than having hardcoded tenant domains.

Thanks,
Cheers.

[1]. https://github.com/wso2-extensions/identity-inbound-auth-saml/blob/v5.1.2/components/org.wso2.carbon.identity.sso.saml/src/main/java/org/wso2/carbon/identity/sso/saml/builders/assertion/DefaultSAMLAssertionBuilder.java#L135

[2]. https://github.com/lkokila/CustomSAMLAssertionBuilder

--

--

Lashan Sivaganeshan

What you search is out there. It's a matter of pressing the right keys.