@@ -47,14 +47,15 @@ def csrf_exempt(view_func):
47
47
from saml2 .metadata import entity_descriptor
48
48
from saml2 .ident import code , decode
49
49
from saml2 .sigver import MissingKey
50
+ from saml2 .s_utils import UnsupportedBinding
50
51
from saml2 .response import StatusError
51
52
from saml2 .xmldsig import SIG_RSA_SHA1 # support for this is required by spec
52
53
53
54
from djangosaml2 .cache import IdentityCache , OutstandingQueriesCache
54
55
from djangosaml2 .cache import StateCache
55
56
from djangosaml2 .conf import get_config
56
57
from 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
58
59
59
60
60
61
logger = logging .getLogger ('djangosaml2' )
@@ -138,7 +139,28 @@ def login(request,
138
139
'came_from' : came_from ,
139
140
})
140
141
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 )
142
164
143
165
client = Saml2Client (conf )
144
166
http_response = None
@@ -187,7 +209,7 @@ def login(request,
187
209
},
188
210
})
189
211
else :
190
- raise NotImplementedError ('Unsupported binding: %s' , binding )
212
+ raise UnsupportedBinding ('Unsupported binding: %s' , binding )
191
213
192
214
# success, so save the session ID and return our response
193
215
logger .debug ('Saving the session_id in the OutstandingQueries cache' )
0 commit comments