|
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