<?php // ####################################################### // Authors: Markus Widmer & Martin Haase // Creation date: 08.07.2007 // Modification date: 07/05/010 // Version: 2.0 // ####################################################### header('Content-Type: text/html; charset=utf-8'); //phpinfo(); require_once( "soapTypes.inc.php" ); $config = new DOMDocument(); $config->load('../../../config_tgwebauth.xml'); $xpath = new DOMXPath($config); $xpath->registerNamespace("c", "http://textgrid.info/namespaces/middleware/tgwebauth"); $authZinstance = $_REQUEST["authZinstance"]; $rbacInstance = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']"); if ($rbacInstance->length == 0) { echo "Error: '${authZinstance}' has no RBAC base configured!<br/>\n"; exit; } $rbacbase = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:rbacbase")->item(0)->nodeValue; $sessionCreatorUid = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:user")->item(0)->nodeValue; $sessionCreatorPw = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:password")->item(0)->nodeValue; $setnamessecret = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:setnamessecret")->item(0)->nodeValue; $slcSupportEnabling = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/@enable"); if ($slcSupportEnabling->length > 0 && $slcSupportEnabling->item(0)->nodeValue === 'true') { $slcMode = TRUE; $slcEntitlementAttributeName = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr/@name")->item(0)->nodeValue; $slcEntitlementAttributeValue = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr")->item(0)->nodeValue; $slcPortalDelegationURL = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:portalDelegationURL")->item(0)->nodeValue; $slcNoDelegationURL = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:noDelegationURL")->item(0)->nodeValue; } else { $slcMode = FALSE; } // the session creation status will collect all messages // during the course of authentication $scstatus = ""; $remote_user = $_SERVER["REMOTE_USER"]; $identity_provider = $_SERVER["Shib-Identity-Provider"]; if (isset($_SERVER["givenName"])) { $givennames = $_SERVER["givenName"];} else { $givennames = "";} if (isset($_SERVER["sn"])) { $surnames = $_SERVER["sn"];} else { $surnames = "";} if (isset($_SERVER["cn"])) { $cns = $_SERVER["cn"];} else { $cns = "";} if (isset($_SERVER["mail"])) { $mails = $_SERVER["mail"];} else { $mails = "";} if (isset($_SERVER["o"])) { $organisations = $_SERVER["o"];} else { $organisations = "";} $identified_user = identify($remote_user, $identity_provider); if ($identified_user['authnmethod'] == 'none') { format_error("User ID not given by home institution", "Your school (its Identity Provider) did not provide a useable User ID to TextGrid.<br/>\n" ."Please contact your school's computing centre and ask them to release to TextGrid's Service Provider " ."at least one of the following attributes: eduPersonPrincipalName, PersistentID or TargetedID. Thank you."); exit; } else { $scstatus .= "Authentication Method: ". $identified_user['authnmethod'] . "; "; $remote_user = $identified_user['user'] . "@" . $identified_user['scope']; } // ----------------------------------------------------- // You'll need these services // ----------------------------------------------------- $soapExtra = new SoapClient( $rbacbase . "wsdl/tgextra.wsdl" ); $soapPolicy = new SoapClient( $rbacbase . "wsdl/tgsystem.wsdl" ); $soapReview = new SoapClient( $rbacbase . "wsdl/tgreview.wsdl" ); $soapAdministration = new SoapClient( $rbacbase . "wsdl/tgadministration.wsdl" ); // ----------------------------------------------------- // Before you can create a session you have to // authenticate. If this was successful you get a // session-ID that you should keep // ----------------------------------------------------- $authReq = new authenticateRequest(); $authReq->username = $sessionCreatorUid; $authReq->password = $sessionCreatorPw; //echo "<HR/>"; //echo "Doing authentication...<BR/>"; try { $authResponse = $soapExtra->authenticate( $authReq ); if( preg_match( "/[0-9a-z]{2,}/i", $authResponse->auth ) ) { $scstatus .= "WebAuth authenticated at RBAC, received an internal SessionId. " ; } } catch( SoapFault $f ) { format_error("Internal Error", "SOAP FAULT (authenticate)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } // ----------------------------------------------------- // Now you can try to add an active role to your session creator session // ----------------------------------------------------- $addRoleReq = new addActiveRoleRequest(); $addRoleReq->username = $sessionCreatorUid; $addRoleReq->role = "sessionCreator,Anwendung"; $addRoleReq->auth = $authResponse->auth; //echo "<HR/>"; //echo "Adding active role...<BR/>"; try { $addRoleResponse = $soapExtra->tgAddActiveRole( $addRoleReq ); if( $addRoleResponse->result ) { //echo "DONE.<BR/>"; $scstatus .= "Added active role of application; "; } else { format_error("Internal Error", "Could not add Role for application."); exit; } } catch( SoapFault $f ) { format_error("Internal Error", "SOAP FAULT (tgAddActiveRole)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } $userexistreq = new userExistsRequest(); $userexistreq->auth = $authResponse->auth; $userexistreq->username = $remote_user; try { $existresult = $soapExtra->userExists($userexistreq); if (! $existresult->result) { try { $adduserrequest = new addUserRequest(); $adduserrequest->intSid = $authResponse->auth; $adduserrequest->username = $remote_user; $adduserrequest->password = "gnuelpfix"; // this is not relevant and will never be checked $addedUser = $soapAdministration->addUser($adduserrequest); if ($addedUser) { $scstatus .= "Added user information to authorization database; "; } else { format_error("Internal Error", "Could not add your user ID to authorization database." ); exit; } } catch(SoapFault $f) { format_error("Internal Error", "SOAP FAULT (AddUser)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } } else { $scstatus .= "user exists in authentication database; "; } } catch (SoapFault $f) { format_error("Internal Error", "SOAP FAULT (UserExists)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } // ----------------------------------------------------- // If this was successful you have to add an appropriate // role to your active session that allows you to create // a session for someone else. // ----------------------------------------------------- $creReq = new createSessionRequest(); $creReq->intSid = $authResponse->auth; //$creReq->username = "mhaase@uni-tuebingen.de"; $creReq->username = $remote_user; //$creReq->roleset = Array( "Projektleiter,Projekt-1,Projekt-Teilnehmer" ); //$creReq->roleset = Array( "Bearbeiter,Projekt-1,Projekt-Teilnehmer" ); // get ALL available roles... $rolesobject = new authorizedRolesRequest(); $rolesobject->intSid = $authResponse->auth; $rolesobject->username = $remote_user; try { $roleResponse = $soapReview->authorizedRoles($rolesobject); // cannot list roles here as they contain "s, which interfere with the // attribute eclosing quotes of the meta tag // $scstatus = $scstatus . "Received all available roles for user: ".serialize($roleResponse->role) . "; "; $scstatus .= "Received all available roles for user; "; } catch (Soapfault $f) { format_error("Internal Error", "SOAP FAULT (authorizedRoles)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } if (is_Array($roleResponse->role)) { $creReq->roleset = $roleResponse->role; } elseif (is_string($roleResponse->role)) { $creReq->roleset = Array($roleResponse->role); } else { $creReq->roleset = Array(); } // Get an newly generated sid from the RBAC system try { $newSid = $soapExtra->getSid(); $newSid = $newSid->sid; } catch (Soapfault $f) { format_error("Internal Error", "RBAC down? Could not generate a new SessionID!" ); exit; } $creReq->sid = $newSid; //echo "Creating the session...<BR/>"; try { $creResponse = $soapPolicy->createSession( $creReq ); if( $creResponse->result ) { //echo "DONE.<BR/>"; $scstatus .= "Created active role; "; } else { $scstatus .= "Could not create active role, proceeding without any role(s) in the session; "; } } catch (SoapFault $f) { format_error("Internal Error", "SOAP FAULT (CreateSession)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } // We will arrive here only if all went well. // Otherwise, format_error() will be called which prints its own header and footer // Header ------------------------------------------------------------ echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"; echo "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n"; echo "<head>\n"; echo "<title>Authentication Succeeded</title>\n"; echo "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n"; // Data -------------------------------------------------------------- echo "<meta name=\"remote_principal\" content=\"$remote_user\"/>\n"; echo "<meta name=\"rbac_session_status\" content=\"$scstatus\"/>\n"; echo "<meta name=\"rbac_sessionid\" content=\"$newSid\"/>\n"; if (!$slcMode) { echo "<meta name=\"ePPNplusSID\" content=\"$remote_user|$newSid\"/>\n"; } echo "<style type=\"text/css\">"; echo "#d123 {display:none;}"; echo "</style>"; echo "<script type=\"text/javascript\">\n"; echo "<!--\n"; echo "function toggle (target) {\n"; echo " var obj=document.getElementById(target);\n"; echo " obj.style.display=\"block\";\n"; echo "}\n"; echo "-->\n"; echo "</script>\n"; echo "</head>\n<body>\n"; echo "<h2>Authentication Succeeded</h2>\n"; echo "<p>You were successfully authenticated with User ID '<b>" . $remote_user . "</b>'. You may now access remote resources using the TextGrid Lab. This window can be closed.</p>\n"; // experimental: Logout //echo "<br/><br/>"; // das hier beendet nur die SP-Session, IdP bleibt... //echo "Click <a href=\"https://auth.textgrid.daasi.de/Shibboleth.sso/Logout\">here</a> if you want to log out."; // das hier sollte den Browser schließen, tuts aber nicht... //echo "<form action=\"\"><input type=\"button\" value=\"Log Out\" onclick=\"window.close()\"></form>"; // also cookies loeschen: //s. http://de.selfhtml.org/javascript/objekte/document.htm#cookie... // Details ----------------------------------------------- echo "<p>More <a href=\"javascript:toggle('d123')\">Details</a>.</p>\n"; echo "<div id=\"d123\"> <h2>Authentication Details</h2>\n"; echo "<table><tr><td>TgAuth Instance</td><td>". $rbacbase ."</td></tr>\n"; echo "<tr><td>Shibboleth Identity ProviderID</td><td>". $identity_provider ."</td></tr>\n"; echo "<tr><td>User ID Attribute Name</td><td>". $identified_user['authnmethod'] ."</td></tr>\n"; echo "<tr><td>User ID Value </td><td>".$remote_user."</td></tr>\n"; echo "<tr><td>Given Name(s)</td><td>".$givennames."</td></tr>\n"; echo "<tr><td>Surname(s)</td><td>".$surnames."</td></tr>\n"; echo "<tr><td>Common Name(s)</td><td>".$cns."</td></tr>\n"; echo "<tr><td>Mail(s)</td><td>".$mails."</td></tr>\n"; echo "<tr><td>Organisation(s)</td><td>".$organisations."</td></tr>\n"; echo "<tr><td>TgAuth Session ID</td><td>".$newSid."</td></tr></table>\n"; echo "</div>"; setNameInRBAC(); if ($slcMode) { $isSLCScompatible = scanEntitlements(); if ($isSLCScompatible) { showCertificateButtons(); } else { showCertificateInfoButton(); } } echo "\n</body>\n</html>"; exit; /////////////////////// Functions /////////////////////////////////////// function format_error ($heading, $detail) { global $remote_user, $scstatus, $newSid, $rbacbase, $identity_provider, $identified_user; // Header ------------------------------------------------------------ echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"; echo "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">"; echo "<head>\n"; echo "<title>Authentication Failed</title>\n"; echo "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n"; echo "<meta name=\"remote_principal\" content=\"$remote_user\"/>\n"; echo "<meta name=\"rbac_session_status\" content=\"$scstatus\"/>\n"; echo "<meta name=\"rbac_sessionid\" content=\"$newSid\"/>\n"; echo "<style type=\"text/css\">"; echo "#d123 {display:none;}"; echo "</style>"; echo "<script type=\"text/javascript\">\n"; echo "<!--\n"; echo "function toggle (target) {\n"; echo " var obj=document.getElementById(target);\n"; echo " obj.style.display=\"block\";\n"; echo "}\n"; echo "-->\n"; echo "</script>\n"; echo "</head>\n\n<body>\n"; echo "<h2>Authentication Failure, $heading</h2>\n"; echo "<p>The Authentication system could not authenticate you.</p>\n"; echo "<p>More <a href=\"javascript:toggle('d123')\">Details</a>.</p>\n"; echo "<div id=\"d123\">"; echo "<h2>Error Details</h2>\n"; echo "<p>". $detail ."</p>" ; echo "<h2>Authentication Details</h2>\n"; echo "<table><tr><td>TgAuth Instance</td><td>". $rbacbase ."</td></tr>\n"; echo "<tr><td>Shibboleth Identity ProviderID</td><td>". $identity_provider ."</td></tr>\n"; echo "<tr><td>User ID Attribute Name</td><td>". $identified_user['authnmethod'] ."</td></tr>\n"; echo "<tr><td>User ID Value </td><td>".$remote_user."</td></tr>\n"; echo "<tr><td>TgAuth Session ID</td><td>".$newSid."</td></tr></table>\n"; echo "</div>"; echo "<p>If not indicated otherwise in the <a href=\"javascript:toggle('d123')\">details</a>, it could be that some service is not responding temporarily. In this case, please <a href=\"javascript:history.back()\">go back</a> or re-open the TextGridLab and try again.</p>"; echo "<p>If the problem persists, please report this bug together with its time of occurence (" . date("Y-m-d H:i:s") . "). In the TextGridLab, choose 'Help->Report Bug'.</p>" ; echo "\n</body>\n</html>"; } function identify ( $remote_user, $idp ) { $authnmethod = "undefined"; $user = "dummy"; $scope = "no-scope.xxx"; if (preg_match('/([^@]+)@([^@]+)/', $remote_user, $matches) == 1) { $authnmethod = "ePPN"; $user = $matches[1]; $scope = $matches[2]; } else if (preg_match('/([^!]+)!([^!]+)!([^!]+)/', $remote_user, $matches) == 1) { $authnmethod = "persistentId"; $user = $matches[3]; $scope = $idp; } else if (strlen($remote_user) > 0) { $authnmethod = "targetedId"; $user = $remote_user; $scope = $idp; } else { $authnmethod = "none"; } $user = escapeForDN($user); $scope = escapeForDN($scope); return array("authnmethod" => $authnmethod, "user" => $user, "scope" => $scope ); } function escapeForDN ($string) { return preg_replace('/[";+<>,\\\]/', "X", $string); } function scanEntitlements () { global $slcEntitlementAttributeName, $slcEntitlementAttributeValue; if (isset($_SERVER[$slcEntitlementAttributeName])) { $entitlements = $_SERVER[$slcEntitlementAttributeName]; $arrEntitlements = explode( ";", $entitlements); foreach ($arrEntitlements as $ent) { if ($ent === $slcEntitlementAttributeValue) { return TRUE; } } } return FALSE; } function showCertificateInfoButton () { global $slcNoDelegationURL, $remote_user, $newSid; echo "<br/><br/>Your account does not include certificate support."; echo "<form method=\"get\" action=\"${slcNoDelegationURL}\">\n"; echo "<input type=\"hidden\" name=\"ePPNplusSID\" value=\"" . $remote_user . "|" .$newSid . "\" />\n"; echo "<input type=\"submit\" value=\"Work without Certificate\"/>\n"; echo "</form>\n"; } function showCertificateButtons () { global $slcPortalDelegationURL, $slcNoDelegationURL, $remote_user, $newSid, $authZinstance; echo "<form method=\"get\" action=\"${slcPortalDelegationURL}\">\n"; echo "<input type=\"hidden\" name=\"userDetails\" value=\"" . $remote_user . "|" .$newSid ."|". $authZinstance . "\">\n"; echo "<input type=\"submit\" value=\"Request Certificate\">\n"; echo "</form>\n\n"; echo "<form method=\"post\" action=\"${slcNoDelegationURL}\">\n"; echo "<input type=\"hidden\" name=\"ePPNplusSID\" value=\"" . $remote_user . "|" .$newSid . "\" />\n"; echo "<input type=\"submit\" value=\"Use Existing Certificate\"/>\n"; echo "</form>\n"; } function setNameInRBAC () { global $givennames, $surnames, $cns, $mails, $organisations, $soapExtra, $newSid, $identity_provider, $remote_user, $setnamessecret; $setNameReq = new setNameRequest(); $setNameReq->auth = $newSid; $setNameReq->log = ""; $setNameReq->webAuthSecret = $setnamessecret; // name will be first cn with a space (s.t. no uid), or "gn1 gn2 gn3 sn1 sn2", or last resort ePPN $cnarr = preg_split ("/;/", $cns ); if ( sizeof ($cnarr) > 0 && preg_match("/ /", $cns) > 0 ) { for ($i = 0; $i < sizeof ($cnarr); $i++) { if (preg_match("/ /", $cnarr[$i]) > 0 ) { $setNameReq->name = $cnarr[$i]; break; } } } elseif ( strlen ($givennames) > 0 && strlen ($surnames) > 0) { $givennameswithspaces = preg_replace ( "/;/", " ", $givennames ); $surnameswithspaces = preg_replace ( "/;/", " ", $surnames ); $setNameReq->name = $givennameswithspaces . " " . $surnameswithspaces; } else { $setNameReq->name = $remote_user; } $setNameReq->mail = $mails; if ( strlen ($organisations) > 0) { $setNameReq->organisation = $organisations; } else { $setNameReq->organisation = $identity_provider; } $setNameReq->agreeSearch = TRUE; try { $setNameResult = $soapExtra->setName( $setNameReq ); if (! $setNameResult->result ) { // do NOT exit as setName is not vital echo "setName: result=false"; } } catch (Soapfault $f) { // do NOT exit as setName is not vital echo "SoapFault"; } } ?>