|
43 | 43 | UnsolicitedResponse) |
44 | 44 | from saml2.s_utils import UnsupportedBinding |
45 | 45 | from saml2.saml import SCM_BEARER |
| 46 | +from saml2.saml import AuthnContextClassRef |
| 47 | +from saml2.samlp import RequestedAuthnContext |
46 | 48 | from saml2.samlp import AuthnRequest, IDPEntry, IDPList, Scoping |
47 | 49 | from saml2.sigver import MissingKey |
48 | 50 | from saml2.validate import ResponseLifetimeExceed, ToEarly |
@@ -133,6 +135,41 @@ def unknown_idp(self, request, idp): |
133 | 135 | msg.format('Please contact technical support.'), status=403 |
134 | 136 | ) |
135 | 137 |
|
| 138 | + def load_sso_kwargs_scoping(self, sso_kwargs): |
| 139 | + """ Performs IdP Scoping if scoping param is present. """ |
| 140 | + idp_scoping_param = self.request.GET.get('scoping', None) |
| 141 | + if idp_scoping_param: |
| 142 | + idp_scoping = Scoping() |
| 143 | + idp_scoping.idp_list = IDPList() |
| 144 | + idp_scoping.idp_list.idp_entry.append( |
| 145 | + IDPEntry(provider_id = idp_scoping_param) |
| 146 | + ) |
| 147 | + sso_kwargs['scoping'] = idp_scoping |
| 148 | + |
| 149 | + def load_sso_kwargs_authn_context(self, sso_kwargs): |
| 150 | + # this would work when https://github.com/IdentityPython/pysaml2/pull/807 |
| 151 | + ac = getattr(self.conf, '_sp_requested_authn_context', {}) |
| 152 | + |
| 153 | + # this works even without https://github.com/IdentityPython/pysaml2/pull/807 |
| 154 | + # hopefully to be removed soon ! |
| 155 | + if not ac: |
| 156 | + scs = getattr( |
| 157 | + settings, 'SAML_CONFIG', {} |
| 158 | + ).get('service', {}).get('sp', {}) |
| 159 | + ac = scs.get('requested_authn_context', {}) |
| 160 | + # end transitional things to be removed soon ! |
| 161 | + |
| 162 | + if ac: |
| 163 | + sso_kwargs["requested_authn_context"] = RequestedAuthnContext( |
| 164 | + authn_context_class_ref=[ |
| 165 | + AuthnContextClassRef(ac['authn_context_class_ref']), |
| 166 | + ], |
| 167 | + comparison = ac.get('comparison', "minimum"), |
| 168 | + ) |
| 169 | + |
| 170 | + def load_sso_kwargs(self, sso_kwargs): |
| 171 | + """ Inherit me if you want to put your desidered things in sso_kwargs """ |
| 172 | + |
136 | 173 | def get(self, request, *args, **kwargs): |
137 | 174 | logger.debug('Login process started') |
138 | 175 | next_path = self.get_next_path(request) |
@@ -166,6 +203,7 @@ def get(self, request, *args, **kwargs): |
166 | 203 | configured_idps = available_idps(conf) |
167 | 204 | selected_idp = request.GET.get('idp', None) |
168 | 205 |
|
| 206 | + self.conf = conf |
169 | 207 | sso_kwargs = {} |
170 | 208 |
|
171 | 209 | # Do we have a Discovery Service? |
@@ -200,16 +238,6 @@ def get(self, request, *args, **kwargs): |
200 | 238 | if selected_idp is None: |
201 | 239 | selected_idp = list(configured_idps.keys())[0] |
202 | 240 |
|
203 | | - # perform IdP Scoping if scoping param is present |
204 | | - idp_scoping_param = request.GET.get('scoping', None) |
205 | | - if idp_scoping_param: |
206 | | - idp_scoping = Scoping() |
207 | | - idp_scoping.idp_list = IDPList() |
208 | | - idp_scoping.idp_list.idp_entry.append( |
209 | | - IDPEntry(provider_id = idp_scoping_param) |
210 | | - ) |
211 | | - sso_kwargs['scoping'] = idp_scoping |
212 | | - |
213 | 241 | # choose a binding to try first |
214 | 242 | binding = getattr(settings, 'SAML_DEFAULT_BINDING', |
215 | 243 | saml2.BINDING_HTTP_POST) |
@@ -267,6 +295,15 @@ def get(self, request, *args, **kwargs): |
267 | 295 | # custom nsprefixes |
268 | 296 | sso_kwargs['nsprefix'] = get_namespace_prefixes() |
269 | 297 |
|
| 298 | + |
| 299 | + # Enrich sso_kwargs ... |
| 300 | + # idp scoping |
| 301 | + self.load_sso_kwargs_scoping(sso_kwargs) |
| 302 | + # authn context |
| 303 | + self.load_sso_kwargs_authn_context(sso_kwargs) |
| 304 | + # other customization to be inherited |
| 305 | + self.load_sso_kwargs(sso_kwargs) |
| 306 | + |
270 | 307 | logger.debug(f'Redirecting user to the IdP via {binding} binding.') |
271 | 308 | _msg = 'Unable to know which IdP to use' |
272 | 309 | http_response = None |
|
0 commit comments