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 2 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_realms>
<shib_realm_name>EGI Proxy IdP</shib_realm_name>
</authentication_realms>
Comment on lines +192 to +194
Copy link
Member

@gregcorbett gregcorbett Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can just be authentication_realm

Suggested change
<authentication_realms>
<shib_realm_name>EGI Proxy IdP</shib_realm_name>
</authentication_realms>
<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_realms>
<shib_realm_name>EGI Proxy IdP</shib_realm_name>
</authentication_realms>
Comment on lines +203 to +205
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with https://github.com/GOCDB/gocdb/pull/524/files#r1842006878

Suggested change
<authentication_realms>
<shib_realm_name>EGI Proxy IdP</shib_realm_name>
</authentication_realms>
<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
30 changes: 30 additions & 0 deletions config/local_info.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,36 @@
</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_realms" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="shib_realm_name" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<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
126 changes: 60 additions & 66 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');
}
if(empty($_SERVER['entitlement'])){
//die('Did not recieve the required entitlement attribute from the EGI Proxy IdP, please contact gocdb-admins');
$HTML = '<ul><li>Login requires a GOCDB entitlement value <a href="https://wiki.egi.eu/wiki/URN_Registry:aai.egi.eu:gocdb" target="_blank">https://wiki.egi.eu/wiki/URN_Registry:aai.egi.eu:gocdb</a></li><li>Please, logout or restart your browser and attempt to login again using an identity provider that provides a GOCDB entitlement</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();
}

$entitlementValuesArray = explode(';', $_SERVER['entitlement']);
if( !in_array('urn:mace:egi.eu:res:gocdb#aai.egi.eu', $entitlementValuesArray) ){
$HTML = '<ul><li>Login requires a GOCDB entitlement <a href="https://wiki.egi.eu/wiki/URN_Registry:aai.egi.eu:gocdb" target="_blank">https://wiki.egi.eu/wiki/URN_Registry:aai.egi.eu:gocdb</a></li><li>Please, logout or restart your browser and attempt to login again using an identity provider that provides a GOCDB entitlement</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();
$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 "
. "IDP $name to complete authentication. "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will read better

Suggested change
. "IDP $name to complete authentication. "
. "$name to complete authentication. "

. "Please contact gocdb-admins."
);
}

if (empty($_SERVER['entitlement'])) {
die(
"Did not receive the required entitlement "
. "attribute from the IDP $name. "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will read better

Suggested change
. "attribute from the IDP $name. "
. "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 IDP $name.</li>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will read better

Suggested change
. "which was not provided for the IDP $name.</li>"
. "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['authenticationRealms']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given https://github.com/GOCDB/gocdb/pull/524/files#r1842006878, this will need a slight tweak

];

return;
}
$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,5 +198,4 @@ public static function isPreAuthenticating() {
public static function isStateless() {
return true;
}

}
55 changes: 55 additions & 0 deletions lib/Gocdb_Services/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -567,4 +567,59 @@ public function getEmailTo()

return $emailTo;
}

public function getIdentityProvidersInfo(): array
{
$localInfo = $this->GetLocalInfoXML();
$identityProviders = [];

if (!empty($localInfo->identity_providers->provider)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens here if identity_providers is omitted in it's entirety from the local_config.xml?

foreach (
$localInfo
->identity_providers
->provider as $providerDetails
) {
Comment on lines +576 to +581
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this I think would read better

Suggested change
if (!empty($localInfo->identity_providers->provider)) {
foreach (
$localInfo
->identity_providers
->provider as $providerDetails
) {
$configured_providers = $localInfo->identity_providers->provider;
if (!empty($configured_providers)) {
foreach ($configured_providers as $providerDetails) {

/** idp */
$idp = (string) $providerDetails->idp;

/** name */
$name = (string) $providerDetails->name;

/** authentication_realms */
$authenticationRealms = [];
if ($providerDetails->authentication_realms) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given https://github.com/GOCDB/gocdb/pull/524/files#r1842006878, this will need a slight tweak

foreach (
$providerDetails
->authentication_realms
->shib_realm_name as $shibRealmName
) {
$authenticationRealms[] = (string) $shibRealmName;
}
}

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

/** help_url */
$helpURL = (string) $providerDetails->help_url;

$identityProviders[] = [
'idp' => $idp,
'name' => $name,
'authenticationRealms' => $authenticationRealms,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given https://github.com/GOCDB/gocdb/pull/524/files#r1842006878

Suggested change
'authenticationRealms' => $authenticationRealms,
'authenticationRealm' => $authenticationRealm,

'requiredGroups' => $requiredGroups,
'helpURL', $helpURL
];
}
}

return $identityProviders;
}
}