package org.apereo.cas.support.saml.web.idp.profile.builders; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.support.saml.OpenSamlConfigBean; import org.apereo.cas.support.saml.SamlException; import org.apereo.cas.support.saml.SamlIdPUtils; import org.apereo.cas.support.saml.services.SamlRegisteredService; import org.apereo.cas.support.saml.services.idp.metadata.SamlRegisteredServiceServiceProviderMetadataFacade; import org.apereo.cas.support.saml.util.AbstractSaml20ObjectBuilder; import org.apereo.cas.util.DateTimeUtils; import org.jasig.cas.client.validation.Assertion; import org.opensaml.saml.saml2.core.AuthnRequest; import org.opensaml.saml.saml2.core.AuthnStatement; import org.opensaml.saml.saml2.core.SubjectLocality; import org.springframework.beans.factory.annotation.Autowired; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.security.SecureRandom; import java.time.ZonedDateTime; /** * This is {@link SamlProfileSamlAuthNStatementBuilder}. * * @author Misagh Moayyed * @since 5.0.0 */ public class SamlProfileSamlAuthNStatementBuilder extends AbstractSaml20ObjectBuilder implements SamlProfileObjectBuilder<AuthnStatement> { private static final long serialVersionUID = 8761566449790497226L; @Autowired private CasConfigurationProperties casProperties; private final AuthnContextClassRefBuilder authnContextClassRefBuilder; public SamlProfileSamlAuthNStatementBuilder(final OpenSamlConfigBean configBean, final AuthnContextClassRefBuilder authnContextClassRefBuilder) { super(configBean); this.authnContextClassRefBuilder = authnContextClassRefBuilder; } @Override public AuthnStatement build(final AuthnRequest authnRequest, final HttpServletRequest request, final HttpServletResponse response, final Assertion assertion, final SamlRegisteredService service, final SamlRegisteredServiceServiceProviderMetadataFacade adaptor, final String binding) throws SamlException { return buildAuthnStatement(assertion, authnRequest, adaptor, service); } /** * Creates an authentication statement for the current request. * * @param assertion the assertion * @param authnRequest the authn request * @param adaptor the adaptor * @param service the service * @return constructed authentication statement * @throws SamlException the saml exception */ private AuthnStatement buildAuthnStatement(final Assertion assertion, final AuthnRequest authnRequest, final SamlRegisteredServiceServiceProviderMetadataFacade adaptor, final SamlRegisteredService service) throws SamlException { final String authenticationMethod = this.authnContextClassRefBuilder.build(assertion, authnRequest, adaptor, service); final String id = '_' + String.valueOf(Math.abs(new SecureRandom().nextLong())); final AuthnStatement statement = newAuthnStatement(authenticationMethod, DateTimeUtils.zonedDateTimeOf(assertion.getAuthenticationDate()), id); if (assertion.getValidUntilDate() != null) { final ZonedDateTime dt = DateTimeUtils.zonedDateTimeOf(assertion.getValidUntilDate()); statement.setSessionNotOnOrAfter( DateTimeUtils.dateTimeOf(dt.plusSeconds(casProperties.getAuthn().getSamlIdp().getResponse().getSkewAllowance()))); } statement.setSubjectLocality(buildSubjectLocality(assertion, authnRequest, adaptor)); return statement; } /** * Build subject locality subject locality. * * @param assertion the assertion * @param authnRequest the authn request * @param adaptor the adaptor * @return the subject locality * @throws SamlException the saml exception */ protected SubjectLocality buildSubjectLocality(final Assertion assertion, final AuthnRequest authnRequest, final SamlRegisteredServiceServiceProviderMetadataFacade adaptor) throws SamlException { final SubjectLocality subjectLocality = newSamlObject(SubjectLocality.class); subjectLocality.setAddress(SamlIdPUtils.getIssuerFromSamlRequest(authnRequest)); return subjectLocality; } }