feat: 🎸 Forward client_id in AuthenticationContextClass

Forward client_id in the AuthenticationContextClass element. This can be
used by the proxy to i.e. display name of the service on WAYF.
pull/1580/head
Dominik Frantisek Bucik 2021-11-11 07:51:57 +01:00
parent 8cf4b64531
commit 6a6d1e3ad9
No known key found for this signature in database
GPG Key ID: 25014C8DB2E7E62D
3 changed files with 66 additions and 3 deletions

View File

@ -133,6 +133,7 @@
<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.acrs.onlyreserved.append">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</prop>
<prop key="saml.user.attrIdentifier">eppn</prop><!-- eppn|epuid|eptid|uid|uniqueIdentifier -->
<!-- STATS JDBC -->
<prop key="stats.jdbc.url">jdbc:mariadb://localhost:3306/STATS</prop>
@ -198,6 +199,7 @@
<property name="idpMetadataFile" value="${saml.idp.metadataLocation}"/>
<property name="idpMetadataUrl" value="${saml.idp.metadataUrl}"/>
<property name="acrReservedPrefixes" value="#{'${saml.acrs.reserverdPrefixes}'.split('\s*,\s*')}"/>
<property name="acrsToBeAdded" value="#{'${saml.acrs.onlyreserved.append}'.split('\s*,\s*')}"/>
<property name="userIdentifierAttribute" value="${saml.user.attrIdentifier}"/>
</bean>

View File

@ -1,8 +1,10 @@
package cz.muni.ics.oidc.saml;
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.CLIENT_ID_PREFIX;
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.EFILTER_PREFIX;
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.FILTER_PREFIX;
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.IDP_ENTITY_ID_PREFIX;
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_CLIENT_ID;
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.PARAM_PROMPT;
import static cz.muni.ics.oidc.server.filters.PerunFilterConstants.REFEDS_MFA;
@ -14,9 +16,13 @@ import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
import cz.muni.ics.oidc.server.filters.PerunFilterConstants;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -43,14 +49,18 @@ public class PerunSamlEntryPoint extends SAMLEntryPoint {
private final PerunAdapter perunAdapter;
private final PerunOidcConfig config;
private final FacilityAttrsConfig facilityAttrsConfig;
private final SamlProperties samlProperties;
@Autowired
public PerunSamlEntryPoint(PerunAdapter perunAdapter, PerunOidcConfig config,
FacilityAttrsConfig facilityAttrsConfig)
public PerunSamlEntryPoint(PerunAdapter perunAdapter,
PerunOidcConfig config,
FacilityAttrsConfig facilityAttrsConfig,
SamlProperties samlProperties)
{
this.perunAdapter = perunAdapter;
this.config = config;
this.facilityAttrsConfig = facilityAttrsConfig;
this.samlProperties = samlProperties;
}
@Override
@ -163,15 +173,57 @@ public class PerunSamlEntryPoint extends SAMLEntryPoint {
options.setForceAuthN(true);
}
if (StringUtils.hasText(request.getParameter(PARAM_CLIENT_ID)) && config.isAddClientIdToAcrs()) {
String clientIdAcr = CLIENT_ID_PREFIX + request.getParameter(PARAM_CLIENT_ID);
log.debug("Adding client_id ACR ({}) to list of AuthnContextClassRefs for purposes" +
" of displaying service name on the wayf", clientIdAcr);
acrs.add(clientIdAcr);
}
if (acrs.size() > 0) {
options.setAuthnContexts(acrs);
log.debug("Transformed acr_values ({}) to SAML AuthnContextClassRef ({})",
acrValues, options.getAuthnContexts());
}
}
private void processAcrs(List<String> acrs) {
if (acrs == null || acrs.isEmpty()) {
return;
}
String[] reservedAcrsPrefixes = samlProperties.getAcrReservedPrefixes();
Set<String> reservedPrefixes = (reservedAcrsPrefixes != null) ?
new HashSet<>(Arrays.asList(reservedAcrsPrefixes)) : new HashSet<>();
if (reservedPrefixes.isEmpty()) {
return;
}
boolean hasNonReserved = false;
for (String prefix: reservedPrefixes) {
for (String acr: acrs) {
if (!acr.startsWith(prefix)) {
log.debug("ACR with non reserved prefix found: {}", acr);
hasNonReserved = true;
break;
}
}
if (hasNonReserved) {
break;
}
}
if (!hasNonReserved) {
List<String> toBeAdded = new LinkedList<>(Arrays.asList(samlProperties.getAcrsToBeAdded()));
log.debug("NO ACR with non reserved prefix found, adding following: {}", toBeAdded);
acrs.addAll(toBeAdded);
}
}
private List<String> convertAcrValuesToList(String acrValues) {
List<String> acrs = new ArrayList<>();
List<String> acrs = new LinkedList<>();
if (StringUtils.hasText(acrValues)) {
String[] parts = acrValues.split(" ");
if (parts.length > 0) {

View File

@ -23,6 +23,7 @@ public class SamlProperties implements InitializingBean {
private String idpMetadataFile;
private String idpMetadataUrl;
private String[] acrReservedPrefixes;
private String[] acrsToBeAdded;
private String userIdentifierAttribute;
public String getEntityID() {
@ -127,6 +128,14 @@ public class SamlProperties implements InitializingBean {
}
}
public String[] getAcrsToBeAdded() {
return acrsToBeAdded;
}
public void setAcrsToBeAdded(String[] acrsToBeAdded) {
this.acrsToBeAdded = acrsToBeAdded;
}
public String getUserIdentifierAttribute() {
return userIdentifierAttribute;
}