feat: 🎸 Extended list of internal referrers for sess. invalider

Via property _saml.internalReferrers_ it can be configured which
referrers are considered as internal and in such a cases session will
not be invalidated. The property has to be list of URLs, separated by a
comma, and the matching is done as a prefix of the current referrer
pull/1580/head
Dominik Frantisek Bucik 2021-11-10 20:27:15 +01:00
parent 39498573c3
commit 9aa16ffe5c
No known key found for this signature in database
GPG Key ID: 25014C8DB2E7E62D
2 changed files with 33 additions and 28 deletions

View File

@ -126,11 +126,11 @@
<prop key="saml.keystore.password">pass</prop>
<prop key="saml.keystore.defaultKey">pass</prop>
<prop key="saml.keystore.defaultKeyPass">pass</prop>
<prop key="saml.idp.defaultIdpEntityId">https://login.cesnet.cz/idp/</prop>
<prop key="saml.idp.defaultIdpEntityId"/>
<prop key="saml.idp.metadataLocation"/> <!-- i.e. /etc/perun/login-cesnet-metadata.xml -->
<prop key="saml.idp.metadataUrl"/> <!-- i.e. https://login.cesnet.cz/proxy/module.php/metadata -->
<prop key="saml.proxy.enabled">true</prop>
<prop key="saml.proxy.spEntityId">https://login.cesnet.cz/proxy/</prop>
<prop key="saml.proxy.spEntityId"/>
<prop key="saml.internalReferrers"/> <!-- comma separated list of URLs (which are matched as prefixes) -->
<prop key="saml.acrs.reserverdPrefixes">urn:cesnet:</prop>
<prop key="saml.acrs.enableComparison">false</prop>
<prop key="saml.user.attrIdentifier">eppn</prop><!-- eppn|epuid|eptid|uid|uniqueIdentifier -->
@ -487,8 +487,8 @@
<constructor-arg name="pattern" value="/authorize**"/>
<constructor-arg name="oidcIssuer" value="${main.oidc.issuer.url}"/>
<constructor-arg name="idpEntityId" value="${saml.idp.defaultIdpEntityId}"/>
<constructor-arg name="proxyEnabled" value="${saml.proxy.enabled}"/>
<constructor-arg name="proxySpEntityId" value="${saml.proxy.spEntityId}"/>
<constructor-arg name="internalReferrers" value="#{'${saml.internalReferrers}'.split('\s*,\s*')}"/>
<constructor-arg name="contextLogoutHandler" ref="logoutHandler"/>
</bean>
<bean id="samlDiscovery" class="org.springframework.security.saml.SAMLDiscovery">

View File

@ -3,6 +3,10 @@ package cz.muni.ics.oidc.saml;
import static org.springframework.http.HttpHeaders.REFERER;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
@ -21,25 +25,34 @@ public class SamlInvalidateSessionFilter extends GenericFilterBean {
private static final Logger log = LoggerFactory.getLogger(SamlInvalidateSessionFilter.class);
private final AntPathRequestMatcher matcher;
private final String idpEntityId;
private final String proxySpEntityId;
private final boolean proxyEnabled;
private final String oidcIssuer;
private final SecurityContextLogoutHandler contextLogoutHandler;
private final List<String> internalReferrers = new ArrayList<>();
public SamlInvalidateSessionFilter(String pattern,
String idpEntityId,
String oidcIssuer,
boolean proxyEnabled,
String proxySpEntityId,
SecurityContextLogoutHandler contextLogoutHandler)
SecurityContextLogoutHandler contextLogoutHandler,
String[] internalReferrers)
{
this.matcher = new AntPathRequestMatcher(pattern);
this.idpEntityId = idpEntityId;
this.oidcIssuer = oidcIssuer;
this.proxyEnabled = proxyEnabled;
this.proxySpEntityId = proxySpEntityId;
if (StringUtils.hasText(idpEntityId)) {
this.internalReferrers.add(idpEntityId);
}
if (StringUtils.hasText(oidcIssuer)) {
this.internalReferrers.add(oidcIssuer);
}
if (StringUtils.hasText(proxySpEntityId)) {
this.internalReferrers.add(proxySpEntityId);
}
this.contextLogoutHandler = contextLogoutHandler;
if (internalReferrers != null && internalReferrers.length > 0) {
List<String> referrers = Arrays.asList(internalReferrers);
referrers = referrers.stream().filter(StringUtils::hasText).collect(Collectors.toList());
if (!referrers.isEmpty()) {
this.internalReferrers.addAll(referrers);
}
}
}
@Override
@ -59,23 +72,15 @@ public class SamlInvalidateSessionFilter extends GenericFilterBean {
}
private boolean isInternalReferer(String referer) {
if (!StringUtils.hasText(referer)) {
// no referer, consider as internal
if (!StringUtils.hasText(referer)) { // no referer, consider as internal
return true;
}
boolean isInternal = referer.startsWith(oidcIssuer);
if (!isInternal) {
if (proxyEnabled) {
// check if referer is PROXY (SP part)
isInternal = referer.startsWith(proxySpEntityId);
} else {
// check if referer is IDP
isInternal = referer.startsWith(idpEntityId);
for (String internal : internalReferrers) {
if (referer.startsWith(internal)) {
return true;
}
}
log.debug("Referer {} is internal: {}", referer, isInternal);
return isInternal;
return false;
}
}