ILIAS  trunk Revision v11.0_alpha-1744-gb0451eebef4
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilShibbolethWAYF.php
Go to the documentation of this file.
1 <?php
2 
21 
33 {
34  public const COOKIE_NAME_SAML_IDP = '_saml_idp';
35  public bool $is_selection = false;
36  public bool $is_valid_selection = false;
37  public string $selected_idp = '-';
38  public array $idp_list = [];
40  protected ilLanguage $lng;
41  protected ilSetting $settings;
42  protected Refinery $refinery;
43 
44  public function __construct()
45  {
46  global $DIC;
47 
48  // Was the WAYF form submitted?
49  $this->wrapper = $DIC->http()->wrapper();
50  $this->refinery = $DIC->refinery();
51  $this->settings = $DIC->settings();
52  $this->is_selection = $this->wrapper->post()->has('home_organization_selection');
53  $this->lng = $DIC->isDependencyAvailable('language')
54  ? $DIC->language()
55  : new ilLanguage(
56  $this->wrapper->query()->has('lang')
57  ? $this->wrapper->query()->retrieve('lang', $DIC->refinery()->to()->string())
58  : null
59  );
60 
61  // Was selected IdP a valid
62  $this->idp_list = $this->getIdplist();
63  $idp_selection = $this->wrapper->post()->has('idp_selection')
64  ? $this->wrapper->post()->retrieve('idp_selection', $DIC->refinery()->to()->string())
65  : null;
66  if ($idp_selection !== null
67  && $idp_selection !== '-'
68  && isset($this->idp_list[$idp_selection])
69  ) {
70  $this->is_valid_selection = true;
71  $this->selected_idp = $idp_selection;
72  } else {
73  $this->is_valid_selection = false;
74  }
75  }
76 
77  public function isSelection(): bool
78  {
79  return $this->is_selection;
80  }
81 
82  public function isValidSelection(): bool
83  {
85  }
86 
87  public function generateSelection(): string
88  {
89  $saml_idp = $this->wrapper->cookie()->has(self::COOKIE_NAME_SAML_IDP)
90  ? $this->wrapper->cookie()->retrieve(
91  self::COOKIE_NAME_SAML_IDP,
92  $this->refinery->kindlyTo()->string()
93  )
94  : null;
95  $idp_cookie = $this->generateCookieArray($saml_idp);
96 
97  $selected_idp = null;
98  if ($idp_cookie !== [] && isset($this->idp_list[end($idp_cookie)])) {
99  $selected_idp = end($idp_cookie);
100  $select_element = '
101  <select name="idp_selection">
102  <option value="-">' . $this->lng->txt("shib_member_of") . '</option>';
103  } else {
104  $select_element = '
105  <select name="idp_selection">
106  <option value="-" selected="selected">' . $this->lng->txt("shib_member_of") . '</option>';
107  }
108 
109  foreach ($this->idp_list as $idp_id => $idp_data) {
110  if ($idp_id === $selected_idp) {
111  $select_element .= '<option value="' . $idp_id . '" selected="selected">' . $idp_data[0] . '</option>';
112  } else {
113  $select_element .= '<option value="' . $idp_id . '">' . $idp_data[0] . '</option>';
114  }
115  }
116 
117  return $select_element . '
118  </select>';
119  }
120 
124  public function redirect(): void
125  {
126  // Where to return after the authentication process
127  $target = $this->wrapper->post()->has('il_target')
128  ? $this->wrapper->post()->retrieve('il_target', $this->refinery->kindlyTo()->string())
129  : '';
130  $target = trim(ILIAS_HTTP_PATH, '/') . '/shib_login.php?target=' . $target;
131  $idp_data = $this->idp_list[$this->selected_idp];
132  if (isset($idp_data[1])) {
133  ilUtil::redirect($idp_data[1] . '?providerId=' . urlencode($this->selected_idp) . '&target='
134  . urlencode($target));
135  } else {
136  // TODO: This has to be changed to /Shibboleth.sso/DS?entityId= for
137  // Shibboleth 2.x sometime...
138  ilUtil::redirect('/Shibboleth.sso?providerId=' . urlencode($this->selected_idp) . '&target='
139  . urlencode($target));
140  }
141  }
142 
146  public function setSAMLCookie(): void
147  {
148  $_saml_idp = $this->wrapper->cookie()->retrieve(self::COOKIE_NAME_SAML_IDP, $this->refinery->kindlyTo()->string());
149  $arr_idps = $_saml_idp ? $this->generateCookieArray($_saml_idp) : [];
150  $arr_idps = $this->appendCookieValue($this->selected_idp, $arr_idps);
151  setcookie(self::COOKIE_NAME_SAML_IDP, $this->generateCookieValue($arr_idps), ['expires' => time() + (100 * 24 * 3600), 'path' => '/']);
152  }
153 
157  public function showNotice(): string
158  {
159  if (!$this->isSelection() || $this->isValidSelection()) {
160  return '';
161  }
162 
163  return $this->lng->txt("shib_invalid_home_organization");
164  }
165 
170  public function getIdplist(): array
171  {
172  $idp_list = [];
173  $idp_raw_list = explode("\n", (string) $this->settings->get("shib_idp_list"));
174  foreach ($idp_raw_list as $idp_line) {
175  $idp_data = explode(',', $idp_line);
176  if (isset($idp_data[2])) {
177  $idp_list[trim($idp_data[0])] = [trim($idp_data[1]), trim($idp_data[2])];
178  } elseif (isset($idp_data[1])) {
179  $idp_list[trim($idp_data[0])] = [trim($idp_data[1])];
180  }
181  }
182 
183  return $idp_list;
184  }
185 
190  public function generateCookieArray(?string $value): array
191  {
192  if (null === $value) {
193  return [];
194  }
195  $arr_cookie = explode(' ', $value);
196  return array_map('base64_decode', $arr_cookie);
197  }
198 
202  public function generateCookieValue(array $arr_cookie): string
203  {
204  $arr_cookie = array_map('base64_encode', $arr_cookie);
205  return implode(' ', $arr_cookie);
206  }
207 
211  public function appendCookieValue(string $value, array $arr_cookie): array
212  {
213  $arr_cookie[] = $value;
214  $arr_cookie = array_reverse($arr_cookie);
215  $arr_cookie = array_unique($arr_cookie);
216  return array_reverse($arr_cookie);
217  }
218 }
generateCookieValue(array $arr_cookie)
Generate the value that is stored in the cookie using the list of IDPs
redirect()
Redirects user to the local Shibboleth session initatiotor with already set GET arguments for the rig...
generateCookieArray(?string $value)
Generates an array of IDPs using the cookie value
appendCookieValue(string $value, array $arr_cookie)
Append a value to the array of IDPs
showNotice()
Show notice in case no IdP was selected
getIdplist()
Generate array of IdPs from ILIAS Shibboleth settings
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
Class ShibbolethWAYF.
global $DIC
Definition: shib_login.php:22
static redirect(string $a_script)
setSAMLCookie()
Sets the standard SAML domain cookie that is also used to preselect the right entry on the local wayf...