![JAR search and dependency download from the Maven repository](/logo.png)
se.swedenconnect.opensaml.sweid.saml2.discovery.SwedishEidDiscoveryMatchingRules Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opensaml-swedish-eid Show documentation
Show all versions of opensaml-swedish-eid Show documentation
OpenSAML 5.X extension library for the Swedish eID Framework
/*
* Copyright 2016-2024 Sweden Connect
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package se.swedenconnect.opensaml.sweid.saml2.discovery;
import java.util.Collection;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.swedenconnect.opensaml.sweid.saml2.metadata.entitycategory.EntityCategoryType;
/**
* A class that implements the Discovery matching rules described in section 1.3 and 1.4 in Entity
* Categories for the Swedish eID Framework.
*
* @author Martin Lindström ([email protected])
*/
public class SwedishEidDiscoveryMatchingRules {
/** Class logger. */
private static final Logger log = LoggerFactory.getLogger(SwedishEidDiscoveryMatchingRules.class);
/**
* Determines if there if the consuming service (SP) may use the providing service (IdP) based on the entity
* categories that they have declared.
*
* The algorithm is defined in section 1.4 of Entity
* Categories for the Swedish eID Framework. The discovery process SHOULD display Identity Providers as a
* plausible choice, if and only if, the following conditions apply;
*
*
* - the Identity Provider declares at least of the Service Entity Category identifiers declared by the Service
* Provider (see {@link #isServiceEntityMatch(Collection, Collection)}),
* - f the Identity Provider declares at least one Service Contract identifier, the Service Provider must declare at
* least one of declared identifiers ({@link #isServiceContractMatch(Collection, Collection)}), and,
* - all of the Service Property identifiers declared by the Service Provider must be declared by the Identity
* Provider ({@link #isServicePropertyMatch(Collection, Collection)}).
*
*
* @param consumingService the entity categories declared by the consuming service (SP)
* @param providingService the entity categories declared by the providing service (IdP)
* @return true if the above algorithm evaluates to {@code true} and {@code false} otherwise
* @see #isServiceEntityMatch(Collection, Collection)
* @see #isServiceContractMatch(Collection, Collection)
* @see #isServicePropertyMatch(Collection, Collection)
*/
public static boolean isMatch(final Collection consumingService, final Collection providingService) {
// 1. Match service entity categories
//
if (!isServiceEntityMatch(consumingService, providingService)) {
return false;
}
// 2. Match service contract identifiers
//
if (!isServiceContractMatch(consumingService, providingService)) {
return false;
}
// 3. Service Property matching
//
if (!isServicePropertyMatch(consumingService, providingService)) {
return false;
}
return true;
}
/**
* Determines if there is a match regarding service entity categories declared by a consuming service and a providing
* service. This is the first condition (out of three) of the algorithm defined in section 1.4 of Entity
* Categories for the Swedish eID Framework.
*
* @param consumingService the entity categories declared by the consuming service (SP)
* @param providingService the entity categories declared by the providing service (IdP)
* @return {@code true} if the providing service declares at least one of the service entity categories declared by
* the consuming service and {@code false} otherwise
*/
public static boolean isServiceEntityMatch(final Collection consumingService,
final Collection providingService) {
final Collection csServiceEntityCategories = consumingService.stream()
.filter(c -> EntityCategoryType.isType(c, EntityCategoryType.SERVICE_ENTITY))
.collect(Collectors.toList());
if (!csServiceEntityCategories.isEmpty()) {
final String matchingServiceEntityCategory = csServiceEntityCategories.stream()
.filter(c -> providingService.contains(c))
.findFirst()
.orElse(null);
if (matchingServiceEntityCategory == null) {
log.debug(
"The providing service did not declare any of the service entity categories declared by the consuming service ({}) -> no match",
csServiceEntityCategories);
return false;
}
log.debug(
"Consuming service declared {} which is also declared by providing service -> service entity category match",
matchingServiceEntityCategory);
}
else {
log.debug("No Service entity entity categories declared by the consuming service -> match");
}
return true;
}
/**
* Determines if there is a match regarding service contract categories declared by a consuming service and a
* providing service. This is the second condition (out of threee) of the algorithm defined in section 1.4 of Entity
* Categories for the Swedish eID Framework.
*
* @param consumingService the entity categories declared by the consuming service (SP)
* @param providingService the entity categories declared by the providing service (IdP)
* @return if the providing service declares at least one service contract category and the consuming service declares
* at least one of those declared identifiers {@code true} is returned
*/
public static boolean isServiceContractMatch(final Collection consumingService,
final Collection providingService) {
final Collection psServiceContractCategories = providingService.stream()
.filter(c -> EntityCategoryType.isType(c, EntityCategoryType.SERVICE_CONTRACT))
.collect(Collectors.toList());
if (!psServiceContractCategories.isEmpty()) {
final String matchingServiceContractCategory = psServiceContractCategories.stream()
.filter(c -> consumingService.contains(c))
.findFirst()
.orElse(null);
if (matchingServiceContractCategory == null) {
log.debug(
"The providing service declared service contract category/categories {}. The consuming service did not declare any of these -> no match",
psServiceContractCategories);
return false;
}
log.debug("Providing service declared {} which is also declared by consuming service -> service contract match",
matchingServiceContractCategory);
}
else {
log.debug("No service contract categories defined by providing service -> match");
}
return true;
}
/**
* Determines if there is a match regarding service property categories declared by a consuming service and a
* providing service. This is the third condition (out of threee) of the algorithm defined in section 1.4 of Entity
* Categories for the Swedish eID Framework.
*
* @param consumingService the entity categories declared by the consuming service (SP)
* @param providingService the entity categories declared by the providing service (IdP)
* @return if all of the Service Property identifiers declared by the consuming service is declared by the providing
* service {@code true} is returned
*/
public static boolean isServicePropertyMatch(final Collection consumingService,
final Collection providingService) {
final Collection csServicePropertyCategories = consumingService.stream()
.filter(c -> EntityCategoryType.isType(c, EntityCategoryType.SERVICE_PROPERTY))
.collect(Collectors.toList());
if (!csServicePropertyCategories.isEmpty()) {
if (!csServicePropertyCategories.stream().allMatch(c -> providingService.contains(c))) {
log.debug(
"Consuming service declared the service property category/categories {} - Not all are defined by providing service -> no match",
csServicePropertyCategories);
return false;
}
log.debug(
"Consuming service declared the category/categories {} which are also declared by providing service -> service property match",
csServicePropertyCategories);
}
else {
log.debug("No service property categories defined by consuming service -> match");
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy