Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
saml_sp.inc
1 <?php
29 class SAML_Service_Provider extends sspmod_saml_Auth_Source_SP
30 {
31 
32 
33 
39  public $entityId;
40 
41 
47  public $metadata;
48 
49 
55  public $idp;
56 
57 
63  public $discoURL;
64 
65 
72  public function __construct($info, $config) {
73  assert('is_array($info)');
74  assert('is_array($config)');
75 
76  /* Call the parent constructor first, as required by the interface. */
77  parent::__construct($info, $config);
78 
79  if(!isset($config[0]) || $config[0] !== 'saml:SP') {
80  trigger_error('The selected authentication source is not SAML Service Provider');
81  exit();
82  }
83 
84  if(!isset($config['entityID'])) {
85  trigger_error('entityID is not found in the selected authentication source');
86  exit();
87  }
88 
89  /* For compatibility with code that assumes that $metadata->getString('entityid') gives the entity id. */
90  $config['entityid'] = $config['entityID'];
91 
92  $this->metadata = SimpleSAML_Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, TRUE) . ']');
93  $this->entityId = $this->metadata->getString('entityID');
94  $this->idp = $this->metadata->getString('idp', NULL);
95  $this->discoURL = $this->metadata->getString('discoURL', NULL);
96 
97  if (empty($this->discoURL) && SimpleSAML_Module::isModuleEnabled('discojuice')) {
98  $this->discoURL = SimpleSAML_Module::getModuleURL('discojuice/central.php');
99  }
100  }
101 
102 
103 
110  public function startSSO($idp, array $state) {
111  assert('is_string($idp)');
112 
113  $idpMetadata = $this->getIdPMetadata($idp);
114 
115  $type = $idpMetadata->getString('metadata-set');
116  switch ($type) {
117  case 'saml20-idp-remote':
118  $this->startSSO2($idpMetadata, $state);
119  assert('FALSE'); /* Should not return. */
120  default:
121  /* Should only be one of the known types. */
122  assert('FALSE');
123  }
124  }
125 
126 
127 
128 
135  public function startSSO2(SimpleSAML_Configuration $idpMetadata, array $state) {
136  if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] < 0) {
137  SimpleSAML_Auth_State::throwException($state, new SimpleSAML_Error_ProxyCountExceeded("ProxyCountExceeded"));
138  }
139 
140  $ar = sspmod_saml_Message::buildAuthnRequest($this->metadata, $idpMetadata);
141 
142  // Set ACS URL as Matrix's ACS asset
143  $ar->setAssertionConsumerServiceURL($state['acs_url']);
144 
145  if (isset($state['SimpleSAML_Auth_Default.ReturnURL'])) {
146  $ar->setRelayState($state['SimpleSAML_Auth_Default.ReturnURL']);
147  }
148 
149  if (isset($state['saml:AuthnContextClassRef'])) {
150  $accr = SimpleSAML_Utilities::arrayize($state['saml:AuthnContextClassRef']);
151  $ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr));
152  }
153 
154  if (isset($state['ForceAuthn'])) {
155  $ar->setForceAuthn((bool)$state['ForceAuthn']);
156  }
157 
158  if (isset($state['isPassive'])) {
159  $ar->setIsPassive((bool)$state['isPassive']);
160  }
161 
162  if (isset($state['ProtocolBinding'])) {
163  $ar->setProtocolBinding($state['ProtocolBinding']);
164  }
165 
166  if (isset($state['saml:NameIDPolicy'])) {
167  if (is_string($state['saml:NameIDPolicy'])) {
168  $policy = array(
169  'Format' => (string)$state['saml:NameIDPolicy'],
170  'AllowCreate' => TRUE,
171  );
172  } elseif (is_array($state['saml:NameIDPolicy'])) {
173  $policy = $state['saml:NameIDPolicy'];
174  } else {
175  throw new SimpleSAML_Error_Exception('Invalid value of $state[\'saml:NameIDPolicy\'].');
176  }
177  $ar->setNameIdPolicy($policy);
178  }
179 
180  if (isset($state['saml:IDPList'])) {
181  $IDPList = $state['saml:IDPList'];
182  } else {
183  $IDPList = array();
184  }
185 
186  $ar->setIDPList(array_unique(array_merge($this->metadata->getArray('IDPList', array()),
187  $idpMetadata->getArray('IDPList', array()),
188  (array) $IDPList)));
189 
190  if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] !== null) {
191  $ar->setProxyCount($state['saml:ProxyCount']);
192  } elseif ($idpMetadata->getInteger('ProxyCount', null) !== null) {
193  $ar->setProxyCount($idpMetadata->getInteger('ProxyCount', null));
194  } elseif ($this->metadata->getInteger('ProxyCount', null) !== null) {
195  $ar->setProxyCount($this->metadata->getInteger('ProxyCount', null));
196  }
197 
198  $requesterID = array();
199  if (isset($state['saml:RequesterID'])) {
200  $requesterID = $state['saml:RequesterID'];
201  }
202 
203  if (isset($state['core:SP'])) {
204  $requesterID[] = $state['core:SP'];
205  }
206 
207  $ar->setRequesterID($requesterID);
208 
209  if (isset($state['saml:Extensions'])) {
210  $ar->setExtensions($state['saml:Extensions']);
211  }
212 
213  $id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso', TRUE);
214  $ar->setId($id);
215 
216  SimpleSAML_Logger::debug('Sending SAML 2 AuthnRequest to ' . var_export($idpMetadata->getString('entityid'), TRUE));
217  if ($this->metadata->getValue('ProtocolBinding') === 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST') {
218  $b = new SAML2_HTTPPost();
219  } else {
220  $b = new SAML2_HTTPRedirect();
221  }
222  $b->send($ar);
223 
224  assert('FALSE');
225  }// end startSSO2()
226 
227 
228 
234  public function startSLO2(&$state) {
235  assert('is_array($state)');
236  assert('array_key_exists("saml:logout:IdP", $state)');
237  assert('array_key_exists("saml:logout:NameID", $state)');
238  assert('array_key_exists("saml:logout:SessionIndex", $state)');
239 
240  $id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent');
241 
242  $idp = $state['saml:logout:IdP'];
243  $nameId = $state['saml:logout:NameID'];
244  $sessionIndex = $state['saml:logout:SessionIndex'];
245 
246  $idpMetadata = $this->getIdPMetadata($idp);
247 
248  $endpoint = $idpMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), FALSE);
249  if ($endpoint === FALSE) {
250  SimpleSAML_Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.');
251  return;
252  }
253 
254  $lr = sspmod_saml_Message::buildLogoutRequest($this->metadata, $idpMetadata);
255  $lr->setNameId($nameId);
256  $lr->setSessionIndex($sessionIndex);
257  $lr->setRelayState($id);
258 
259 
260  $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', NULL);
261  if ($encryptNameId === NULL) {
262  $encryptNameId = $this->metadata->getBoolean('nameid.encryption', FALSE);
263  }
264  if ($encryptNameId) {
265  $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($idpMetadata));
266  }
267 
268  if ($this->metadata->getValue('ProtocolBinding') === 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST') {
269  $b = new SAML2_HTTPPost();
270  } else {
271  $b = new SAML2_HTTPRedirect();
272  }
273  $b->send($lr);
274 
275  assert('FALSE');
276  }// end startSLO2()
277 
278 
279 
280 
281 }// end class
282 
283 
284 ?>