<?php // ####################################################### // Author: Martin Haase / DAASI International GmbH / TextGrid // Creation date: 2010-10-13 // Modification date: 2010-10-13 // Version: 0.1 // based on TextGrid-Webauth.php // ####################################################### mb_internal_encoding("UTF-8"); class RBAC { // Global variables protected $authZinstance; protected $rbacbase; protected $sessionCreatorUid; protected $sessionCreatorPw; protected $setnamessecret; protected $soapExtra; protected $soapPolicy; protected $soapReview; protected $soapAdministration; protected $userAttributes; protected $SLCdata; public function __construct( $configfilepath , $authZinstance ) { require_once( "soapTypes.inc.php" ); $config = new DOMDocument(); $config->load($configfilepath); $xpath = new DOMXPath($config); $xpath->registerNamespace("c", "http://textgrid.info/namespaces/middleware/tgwebauth"); $this->rbacbase = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:rbacbase")->item(0)->nodeValue; if (!isset ($this->rbacbase) || strlen($this->rbacbase) == 0) { echo "Error: '${authZinstance}' has no RBAC base configured!<br/>\n"; return null; } $this->authZinstance = $authZinstance; $this->sessionCreatorUid = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:user")->item(0)->nodeValue; $this->sessionCreatorPw = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:password")->item(0)->nodeValue; $this->setnamessecret = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:setnamessecret")->item(0)->nodeValue; $this->SLCdata = array(); $slcSupportEnabling = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/@enable"); if ($slcSupportEnabling->length > 0 && $slcSupportEnabling->item(0)->nodeValue === 'true') { $this->SLCdata['slcMode'] = TRUE; $this->SLCdata['slcEntitlementAttributeName'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr/@name")->item(0)->nodeValue; $this->SLCdata['slcEntitlementAttributeValue'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr")->item(0)->nodeValue; $this->SLCdata['slcPortalDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:portalDelegationURL")->item(0)->nodeValue; $this->SLCdata['slcNoDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:noDelegationURL")->item(0)->nodeValue; } else { $this->SLCdata['slcMode'] = FALSE; } // ----------------------------------------------------- // You'll need these services // ----------------------------------------------------- $this->soapExtra = new SoapClient( $this->rbacbase . "wsdl/tgextra.wsdl" ); $this->soapPolicy = new SoapClient( $this->rbacbase . "wsdl/tgsystem.wsdl" ); $this->soapReview = new SoapClient( $this->rbacbase . "wsdl/tgreview.wsdl" ); $this->soapAdministration = new SoapClient( $this->rbacbase . "wsdl/tgadministration.wsdl" ); } public function slcData() { return $this->SLCdata; } public function createSession ( $remote_user ) { $rbachash = array("scstatus" => "", // will collect all messages during authentication "Sid" => "none", // this will hold the final sessionId then "rbacbase" => $this->rbacbase, 'authZinstance' => $this->authZinstance ); // ------------------------------------------------------------ // check whether remote_user is set and has user@domain format if (preg_match('/([^@]+)@([^@]+)/', $remote_user, $matches) == 1) { $identified_user = array("authnmethod" => "eduPersonPrincipalName", "user" => $matches[1], "scope" => $matches[2] ); $identified_user['user'] = $this->escapeForDN ($identified_user['user']); $identified_user['scope'] = $this->escapeForDN ($identified_user['scope']); $remote_user = $identified_user['user'] . "@" . $identified_user['scope']; $rbachash["identified_user"] = $identified_user; $rbachash["remote_user"] = $remote_user; // TG User ID } else { return array("success" => FALSE, "detail" => "User ID not given by home institution.<br/>\n" ."Your school (its Identity Provider) did not provide a useable User ID to TextGrid (".$remote_user .").<br/>\n" ."Please contact your school's computing centre and ask them to release to TextGrid's Service Provider " ."the eduPersonPrincipalName attribute.<br/>Thank you.", "rbachash" => $rbachash); exit; } $rbachash["scstatus"] .= "Authentication Method: ". $identified_user['authnmethod'] . "; "; // ----------------------------------------------------- // Before you can create a session you have to // authenticate. If this was successful you get a // session-ID that you should keep // ----------------------------------------------------- $serviceAuthReq = new authenticateRequest(); $serviceAuthReq->username = $this->sessionCreatorUid; $serviceAuthReq->password = $this->sessionCreatorPw; try { $serviceAuthResponse = $this->soapExtra->authenticate( $serviceAuthReq ); if( preg_match( "/[0-9a-z]{2,}/i", $serviceAuthResponse->auth ) ) { $rbachash["scstatus"] .= "WebAuth authenticated at RBAC, received a service SessionId. " ; } } catch( SoapFault $f ) { return array("success" => FALSE, "detail" => "SOAP FAULT (authenticate)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail, "rbachash" => $rbachash); exit; } // ----------------------------------------------------- // Now you can try to add an active role to your session creator session // ----------------------------------------------------- $addRoleReq = new addActiveRoleRequest(); $addRoleReq->username = $this->sessionCreatorUid; $addRoleReq->role = "sessionCreator,Anwendung"; $addRoleReq->auth = $serviceAuthResponse->auth; try { $addRoleResponse = $this->soapExtra->tgAddActiveRole( $addRoleReq ); if( $addRoleResponse->result ) { $rbachash["scstatus"] .= "Added active role of application; "; } else { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "Internal Error, Could not add Role for application."); exit; } } catch( SoapFault $f ) { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "SOAP FAULT (tgAddActiveRole)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail); exit; } // ----------------------------------------------------- // Check whether user exists already in RBAC // ----------------------------------------------------- $userexistreq = new userExistsRequest(); $userexistreq->auth = $serviceAuthResponse->auth; $userexistreq->username = $remote_user; try { $existresult = $this->soapExtra->userExists($userexistreq); if (! $existresult->result) { // ----------------------------------------------- // User does not exist, so add 'em $adduserrequest = new addUserRequest(); $adduserrequest->intSid = $serviceAuthResponse->auth; $adduserrequest->username = $remote_user; $adduserrequest->password = "gnuelpfix"; // this is not relevant and will never be checked try { $addedUser = $this->soapAdministration->addUser($adduserrequest); if ($addedUser) { $rbachash["scstatus"] .= "Added user information to authorization database; "; } else { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "Could not add your user ID to authorization database." ); exit; } } catch(SoapFault $f) { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "SOAP FAULT (AddUser)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } } else { $rbachash["scstatus"] .= "user exists in authentication database; "; } } catch (SoapFault $f) { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "SOAP FAULT (UserExists)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } // ----------------------------------------------------- // If this was successful you can create the session for remote_user // need to add active roles to the session // ----------------------------------------------------- $creReq = new createSessionRequest(); $creReq->intSid = $serviceAuthResponse->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 = $serviceAuthResponse->auth; $rolesobject->username = $remote_user; try { $roleResponse = $this->soapReview->authorizedRoles($rolesobject); $rbachash["scstatus"] .= "Received all available roles for user; "; } catch (Soapfault $f) { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "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 a newly generated sid from the RBAC system try { $Sid = $this->soapExtra->getSid(); $Sid = $Sid->sid; $rbachash["Sid"] = $Sid; } catch (Soapfault $f) { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "RBAC down? Could not generate a new SessionID!" ); exit; } // ------------------------------------- // Creating the session... $creReq->sid = $Sid; try { $creResponse = $this->soapPolicy->createSession( $creReq ); if( $creResponse->result ) { $rbachash["scstatus"] .= "Created sessions with active roles; "; } else { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "Failed to create a new Session!" ); exit; } } catch (SoapFault $f) { return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "SOAP FAULT (CreateSession)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } // -------------------------------------------------------- // now all went well, createSession worked, return success return array("success" => TRUE, "rbachash" => $rbachash); } // see RFC XYZ, DN Syntax function escapeForDN ($string) { return preg_replace('/[";+<>,\\\]/', "X", $string); } function getUserAttributes ( $Sid ) { $getMyUAR = new StdClass(); $getMyUAR->auth = $Sid; try { $ua = $this->soapExtra->getMyUserAttributes($getMyUAR); $this->userAttributes = $ua->attribute; return $ua->attribute; } catch (SoapFault $f) { return array("success" => FALSE, "detail" => "SOAP FAULT (getMyUserAttributes)!: " . serialize ($f) ); } } function enoughUserAttributes ( $Sid ) { if (!isset($this->userAttributes)) { $this->getUserAttributes( $Sid ); } // $file = fopen ("/tmp/xxxR.log", "w+"); // fwrite ($file, serialize ($this->userAttributes ) ."\n"); // fclose ($file); foreach ($this->userAttributes as $a) { if ($a->mandatory) { if (!isset($a->value)) { return FALSE; } else { if (is_string($a->value) && strlen($a->value) < 1) { return FALSE; } } } } return TRUE; } function updateAttributes ( $attrs, $map, $Sid ) { $newattributes = array(); foreach ($map as $name => $value) { if (isset($attrs[$value])) { $na = new StdClass(); $na->name = $name; $na->value = $attrs[$value]; $newattributes[] = $na; } } return $this->setAttributes ($newattributes, $Sid, TRUE); } function setAttributes ( $attrs, $Sid, $loginmode ) { $setMyUserAttributesRequest = new StdClass(); $setMyUserAttributesRequest->attribute = $attrs; $setMyUserAttributesRequest->auth = $Sid; if ($loginmode) { $setMyUserAttributesRequest->webAuthSecret = $this->setnamessecret; } else { $setMyUserAttributesRequest->webAuthSecret = ""; } try { $res = $this->soapExtra->setMyUserAttributes($setMyUserAttributesRequest); return $res; } catch (SoapFault $f) { return array("success" => FALSE, "detail" => "SOAP FAULT (setMyUserAttributes)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); } } } ?>