@@ -47,14 +47,15 @@ def csrf_exempt(view_func):
4747from saml2 .metadata import entity_descriptor
4848from saml2 .ident import code , decode
4949from saml2 .sigver import MissingKey
50+ from saml2 .s_utils import UnsupportedBinding
5051from saml2 .response import StatusError
5152from saml2 .xmldsig import SIG_RSA_SHA1 # support for this is required by spec
5253
5354from djangosaml2 .cache import IdentityCache , OutstandingQueriesCache
5455from djangosaml2 .cache import StateCache
5556from djangosaml2 .conf import get_config
5657from djangosaml2 .signals import post_authenticated
57- from djangosaml2 .utils import get_custom_setting , available_idps , get_location
58+ from djangosaml2 .utils import get_custom_setting , available_idps , get_location , get_idp_sso_supported_bindings
5859
5960
6061logger = logging .getLogger ('djangosaml2' )
@@ -138,7 +139,28 @@ def login(request,
138139 'came_from' : came_from ,
139140 })
140141
141- binding = BINDING_HTTP_POST if getattr (conf , '_sp_authn_requests_signed' , False ) else BINDING_HTTP_REDIRECT
142+ # choose a binding to try first
143+ sign_requests = getattr (conf , '_sp_authn_requests_signed' , False )
144+ binding = BINDING_HTTP_POST if sign_requests else BINDING_HTTP_REDIRECT
145+ logger .debug ('Trying binding %s for IDP %s' , binding , selected_idp )
146+
147+ # ensure our selected binding is supported by the IDP
148+ supported_bindings = get_idp_sso_supported_bindings (selected_idp , config = conf )
149+ if binding not in supported_bindings :
150+ logger .debug ('Binding %s not in IDP %s supported bindings: %s' ,
151+ binding , selected_idp , supported_bindings )
152+ if binding == BINDING_HTTP_POST :
153+ logger .warning ('IDP %s does not support %s, trying %s' ,
154+ selected_idp , binding , BINDING_HTTP_REDIRECT )
155+ binding = BINDING_HTTP_REDIRECT
156+ else :
157+ logger .warning ('IDP %s does not support %s, trying %s' ,
158+ selected_idp , binding , BINDING_HTTP_POST )
159+ binding = BINDING_HTTP_POST
160+ # if switched binding still not supported, give up
161+ if binding not in supported_bindings :
162+ raise UnsupportedBinding ('IDP %s does not support %s or %s' ,
163+ selected_idp , BINDING_HTTP_POST , BINDING_HTTP_REDIRECT )
142164
143165 client = Saml2Client (conf )
144166 http_response = None
@@ -187,7 +209,7 @@ def login(request,
187209 },
188210 })
189211 else :
190- raise NotImplementedError ('Unsupported binding: %s' , binding )
212+ raise UnsupportedBinding ('Unsupported binding: %s' , binding )
191213
192214 # success, so save the session ID and return our response
193215 logger .debug ('Saving the session_id in the OutstandingQueries cache' )
0 commit comments