Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config for identity_providers in local_info.xml #524

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions config/local_info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,37 @@
-->
<restrict_personal_data>false</restrict_personal_data>

<!-- identity_providers
Shib/CheckIn Token reads config file
for needed AAI entitlements.
This is to allow Admins so that they will be empowered
to make quicker changes to AAI references.
-->
<identity_providers>
<provider>
<idp>aai.egi.eu/auth/realms/egi</idp>
<name>EGI Proxy</name>
<authentication_realm>
EGI Proxy IdP
</authentication_realm>
<required_groups>
<group>urn:mace:egi.eu:res:gocdb#aai.egi.eu</group>
</required_groups>
<help_url>https://docs.egi.eu/internal/configuration-database/access/#using-institutional-account-via-egi-check-in</help_url>
</provider>
<provider>
<idp>aai-demo.egi.eu/auth/realms/egi</idp>
<name>EGI Demo Proxy</name>
<authentication_realm>
EGI Proxy IdP
</authentication_realm>
<required_groups>
<group>urn:mace:egi.eu:res:gocdb#aai.egi.eu</group>
</required_groups>
<help_url>https://docs.egi.eu/internal/configuration-database/access/#using-institutional-account-via-egi-check-in</help_url>
</provider>
</identity_providers>

</local_info>

<!--
Expand Down
24 changes: 24 additions & 0 deletions config/local_info.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,30 @@
</xs:complexType>
</xs:element>
<xs:element name="send_email" type="xs:boolean" minOccurs="0"/>

<xs:element name="identity_providers" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="provider" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="idp" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="authentication_realm" minOccurs="1" maxOccurs="1" />
<xs:element name="required_groups" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="group" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="help_url" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="url" type="xs:anyURI"/>
</xs:complexType>
Expand Down
149 changes: 60 additions & 89 deletions lib/Authentication/AuthTokens/ShibAuthToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ private function getAttributesInitToken(){
// specify location of the Shib Logout handler
\Factory::$properties['LOGOUTURL'] = 'https://'.$hostname.'/Shibboleth.sso/Logout';
$idp = isset($_SERVER['Shib-Identity-Provider']) ? $_SERVER['Shib-Identity-Provider'] : '';

if ($idp == 'https://unity.eudat-aai.fz-juelich.de:8443/saml-idp/metadata'
&& $_SERVER['distinguishedName'] != null){
$this->principal = $_SERVER['distinguishedName'];
Expand All @@ -96,73 +97,67 @@ private function getAttributesInitToken(){
$this->userDetails = array('AuthenticationRealm' => array('UK_ACCESS_FED'));
return;
}
else if($idp == 'https://aai.egi.eu/auth/realms/egi'){
// assurance is the old way EGI checkIn used to pass LoA attributes
/*if( empty($_SERVER['voPersonID'])){// || empty($_SERVER['displayName']) ){
die('Did not recieve required attributes from the EGI Proxy Identity Provider to complete authentication, please contact gocdb-admins');
}
if(empty($_SERVER['assurance'])){
die('Did not receive the required assurance attribute from the EGI Proxy IdP, please contact gocdb-admins');
}
if($_SERVER['assurance'] != 'https://aai.egi.eu/LoA#Substantial'){
$HTML = '<ul><li>You authenticated to the EGI Identity Provider using a method that provides an inadequate Level of Assurance for GOCDB (weak user verification).</li><li>Login is required with an assurance level of [Substantial].</li><li>To gain access, you will need to login to the Proxy IdP using a scheme that provides [LoA#Substantial].</li><li>Please logout or restart your browser and attempt to login again.</li></ul>';
$HTML .= "<div style='text-align: center;'>";
$HTML .= '<a href="'.htmlspecialchars(\Factory::$properties['LOGOUTURL']).'"><b><font colour="red">Logout</font></b></a>';
$HTML .= "</div>";
echo ($HTML);
die();
}
$this->principal = $_SERVER['voPersonID'];
$this->userDetails = array('AuthenticationRealm' => array('EGI Proxy IdP'));
return;
*/

if( empty($_SERVER['voPersonID'])){// || empty($_SERVER['displayName']) ){
die('Did not recieve required attributes from the EGI Proxy Identity Provider to complete authentication, please contact gocdb-admins');
$configService = \Factory::getConfigService();
$identityProviders = $configService->getIdentityProvidersInfo();

foreach ($identityProviders as $provider) {
if ($provider['idp'] === $idp) {
$name = $provider['name'];
$helpUrl = $provider['help_url'];

if (empty($_SERVER['voPersonID'])) {
die(
"Did not receive required attributes from the "
. "$name to complete authentication. "
. "Please contact gocdb-admins."
);
}

if (empty($_SERVER['entitlement'])) {
die(
"Did not receive the required entitlement "
. "attribute from the $name. "
. "Please contact gocdb-admins."
);
}

if (!empty($provider['required_groups'])) {
$entitlementValues = explode(';', $_SERVER['entitlement']);

if (
!array_intersect(
$entitlementValues,
$provider['required_groups']
)
) {
$HTML = "<ul>"
. "<li>Login requires a GOCDB entitlement value "
. "which was not provided for the $name.</li>"
. "<li>Please see here for more information: "
. "<a href='$helpUrl' target='_blank'>"
. "$helpUrl</a>.</li>"
. "<li>Logout or restart your browser"
. "and attempt to login again using an IDP "
. "that provides a GOCDB entitlement.</li>"
. "</ul>";
$HTML .= "<div style='text-align: center;'>";
$HTML .= "<a href=\""
. htmlspecialchars(\Factory::$properties['LOGOUTURL'])
. "\"><b><font color=\"red\">Logout</font></b></a>";
$HTML .= "</div>";
echo ($HTML);
die();
}
}

$this->principal = $_SERVER['voPersonID'];
$this->userDetails = [
'AuthenticationRealm' => $provider['authenticationRealm']
];

return;
}
if(empty($_SERVER['entitlement'])){
//die('Did not recieve the required entitlement attribute from the EGI Proxy IdP, please contact gocdb-admins');
$HTML = $this->getEntitlementErrorMessage();
$HTML .= "<div style='text-align: center;'>";
$HTML .= '<a href="'.htmlspecialchars(\Factory::$properties['LOGOUTURL']).'"><b><font colour="red">Logout</font></b></a>';
$HTML .= "</div>";
echo ($HTML);
die();
}

$entitlementValuesArray = explode(';', $_SERVER['entitlement']);
if( !in_array('urn:mace:egi.eu:res:gocdb#aai.egi.eu', $entitlementValuesArray) ){
$HTML = $this->getEntitlementErrorMessage();
$HTML .= "<div style='text-align: center;'>";
$HTML .= '<a href="'.htmlspecialchars(\Factory::$properties['LOGOUTURL']).'"><b><font colour="red">Logout</font></b></a>';
$HTML .= "</div>";
echo ($HTML);
die();
}
$this->principal = $_SERVER['voPersonID'];
$this->userDetails = array('AuthenticationRealm' => array('EGI Proxy IdP'));
return;

}
else if($idp == 'https://aai-demo.egi.eu/auth/realms/egi'){
if( empty($_SERVER['voPersonID'])){
die('Did not receive required voPersonID attributes from the EGI Demo Proxy Identity Provider to complete authentication, please contact gocdb-admins');
}
if(empty($_SERVER['entitlement'])){
die('Did not receive the required entitlement attribute from the EGI Demo Proxy IdP, please contact gocdb-admins');
}
$entitlementValuesArray = explode(';', $_SERVER['entitlement']);
if( !in_array('urn:mace:egi.eu:res:gocdb#aai.egi.eu', $entitlementValuesArray) ){
$HTML = '<ul><li>You authenticated to the EGI Demo Identity Provider using a method that does not provide a GOCDB entitlement.</li><li>Login is required with a gocdb entitlement.</li><li>To gain access, you will need to login to the Proxy IdP using a scheme that provides a gocdb entitlement.</li><li>Please logout or restart your browser and attempt to login again.</li></ul>';
$HTML .= "<div style='text-align: center;'>";
$HTML .= '<a href="'.htmlspecialchars(\Factory::$properties['LOGOUTURL']).'"><b><font colour="red">Logout</font></b></a>';
$HTML .= "</div>";
echo ($HTML);
die();
}
$this->principal = $_SERVER['voPersonID'];
$this->userDetails = array('AuthenticationRealm' => array('EGI Proxy IdP'));
return;
}
}

Expand Down Expand Up @@ -203,28 +198,4 @@ public static function isPreAuthenticating() {
public static function isStateless() {
return true;
}

private function getEntitlementErrorMessage()
{
$refedsResAndSchURL = "https://refeds.org/category/research-and-scholarship";
$refedsSirtfiURL = "https://refeds.org/sirtfi";
$resourceLink = "https://docs.egi.eu/internal/configuration-database/access";
$sectionFragmentInfo = "/#using-institutional-account-via-egi-check-in";
$documentationURL = $resourceLink . $sectionFragmentInfo;

return "<ul>"
. "<li>Login requires the entitlement "
. "urn:mace:egi.eu:res:gocdb#aai.egi.eu, "
. "which was not provided.</li>"
. "<li>This entitlement is automatically granted "
. "when using an identity provider compliant with "
. "<a href=\"{$refedsResAndSchURL}\" target='_blank'>"
. "REFEDS R&amp;S</a> and "
. "<a href=\"{$refedsSirtfiURL}\" target='_blank'>"
. "REFEDS Sirtfi</a>.</li>"
. "<li>Please see here for more information: "
. "<a href=\"{$documentationURL}\" target='_blank'>"
. "{$documentationURL}</a>.</li>"
. "</ul>";
}
}
40 changes: 40 additions & 0 deletions lib/Gocdb_Services/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -567,4 +567,44 @@ public function getEmailTo()

return $emailTo;
}

public function getIdentityProvidersInfo()
{
$localInfo = $this->GetLocalInfoXML();
$configuredProviders = $localInfo->identity_providers->provider;
$identityProviders = [];

if (!empty($configuredProviders)) {
foreach ($configuredProviders as $providerDetails) {
$identityProviders[] = $this->extractProviderInfo(
$providerDetails);
}
}

return $identityProviders;
}

private function extractProviderInfo($providerDetails)
{
/** required_groups */
$requiredGroups = [];

if (!empty($providerDetails->required_groups)) {
foreach ($providerDetails->required_groups->group as $group) {
$requiredGroups[] = (string) $group;
}
}

// Return extracted provider information as an array
return [
'idp' => (string) $providerDetails->idp,
'name' => (string) $providerDetails->name,
'authenticationRealm' => [
(string) $providerDetails->authentication_realm
],
'requiredGroups' => $requiredGroups,
'helpURL' => (string) $providerDetails->help_url
];
}

}
Loading