Display an error message on bad response from identity provider in federate mode. fix #7.
If the identity provider CAS do not return an XML document as specified on ticket validation, an XML parsing error is raised. We now catch it and display a message to the user.
This commit is contained in:
parent
2cc31ce5f5
commit
34118833bf
@ -183,7 +183,8 @@ class FederateAuthLoginLogoutTestCase(
|
|||||||
"""
|
"""
|
||||||
The federated view should redirect to /login if the provider is unknown or not provided,
|
The federated view should redirect to /login if the provider is unknown or not provided,
|
||||||
try to fetch a new ticket if the provided ticket validation fail
|
try to fetch a new ticket if the provided ticket validation fail
|
||||||
(network error or bad ticket)
|
(network error or bad ticket), redirect to /login with a error message if identity
|
||||||
|
provider CAS return a bad response (invalid XML document)
|
||||||
"""
|
"""
|
||||||
good_provider = "example.com"
|
good_provider = "example.com"
|
||||||
bad_provider = "exemple.fr"
|
bad_provider = "exemple.fr"
|
||||||
@ -229,6 +230,18 @@ class FederateAuthLoginLogoutTestCase(
|
|||||||
'http://testserver' if django.VERSION < (1, 9) else ""
|
'http://testserver' if django.VERSION < (1, 9) else ""
|
||||||
))
|
))
|
||||||
|
|
||||||
|
# test CAS avaible but return a bad XML doc, should redirect to /login with a error message
|
||||||
|
# use "example.net" as it is CASv3
|
||||||
|
tests_utils.HttpParamsHandler.run(8082)
|
||||||
|
response = client.get("/federate/%s" % "example.net", {'ticket': utils.gen_st()})
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response["Location"], "%s/login" % (
|
||||||
|
'http://testserver' if django.VERSION < (1, 9) else ""
|
||||||
|
))
|
||||||
|
response = client.get("/login")
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertIn(b"Invalid response from your identity provider CAS", response.content)
|
||||||
|
|
||||||
def test_auth_federate_slo(self):
|
def test_auth_federate_slo(self):
|
||||||
"""test that SLO receive from backend CAS log out the users"""
|
"""test that SLO receive from backend CAS log out the users"""
|
||||||
# get tickets and connected clients
|
# get tickets and connected clients
|
||||||
|
@ -312,31 +312,49 @@ class FederateAuth(View):
|
|||||||
return HttpResponseRedirect(auth.get_login_url())
|
return HttpResponseRedirect(auth.get_login_url())
|
||||||
else:
|
else:
|
||||||
ticket = request.GET['ticket']
|
ticket = request.GET['ticket']
|
||||||
# if the ticket validation succeed
|
try:
|
||||||
if auth.verify_ticket(ticket):
|
# if the ticket validation succeed
|
||||||
logger.info(
|
if auth.verify_ticket(ticket):
|
||||||
"Got a valid ticket for %s from %s" % (
|
logger.info(
|
||||||
auth.username,
|
"Got a valid ticket for %s from %s" % (
|
||||||
auth.provider.server_url
|
auth.username,
|
||||||
|
auth.provider.server_url
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
params = utils.copy_params(request.GET, ignore={"ticket"})
|
||||||
params = utils.copy_params(request.GET, ignore={"ticket"})
|
request.session["federate_username"] = auth.federated_username
|
||||||
request.session["federate_username"] = auth.federated_username
|
request.session["federate_ticket"] = ticket
|
||||||
request.session["federate_ticket"] = ticket
|
auth.register_slo(
|
||||||
auth.register_slo(auth.federated_username, request.session.session_key, ticket)
|
auth.federated_username,
|
||||||
# redirect to the the login page for the user to become authenticated
|
request.session.session_key,
|
||||||
# thanks to the `federate_username` and `federate_ticket` session parameters
|
ticket
|
||||||
url = utils.reverse_params("cas_server:login", params)
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
# else redirect to the identity provider CAS login page
|
|
||||||
else:
|
|
||||||
logger.info(
|
|
||||||
"Got a invalid ticket for %s from %s. Retrying to authenticate" % (
|
|
||||||
auth.username,
|
|
||||||
auth.provider.server_url
|
|
||||||
)
|
)
|
||||||
|
# redirect to the the login page for the user to become authenticated
|
||||||
|
# thanks to the `federate_username` and `federate_ticket` session parameters
|
||||||
|
url = utils.reverse_params("cas_server:login", params)
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
# else redirect to the identity provider CAS login page
|
||||||
|
else:
|
||||||
|
logger.info(
|
||||||
|
"Got a invalid ticket for %s from %s. Retrying to authenticate" % (
|
||||||
|
auth.username,
|
||||||
|
auth.provider.server_url
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return HttpResponseRedirect(auth.get_login_url())
|
||||||
|
# both xml.etree.ElementTree and lxml.etree exceptions inherit from SyntaxError
|
||||||
|
except SyntaxError as error:
|
||||||
|
messages.add_message(
|
||||||
|
request,
|
||||||
|
messages.ERROR,
|
||||||
|
_(
|
||||||
|
u"Invalid response from your identity provider CAS upon "
|
||||||
|
u"ticket %s validation: %r"
|
||||||
|
) % (ticket, error)
|
||||||
)
|
)
|
||||||
return HttpResponseRedirect(auth.get_login_url())
|
response = redirect("cas_server:login")
|
||||||
|
response.delete_cookie("_remember_provider")
|
||||||
|
return response
|
||||||
except FederatedIendityProvider.DoesNotExist:
|
except FederatedIendityProvider.DoesNotExist:
|
||||||
logger.warning("Identity provider suffix %s not found" % provider)
|
logger.warning("Identity provider suffix %s not found" % provider)
|
||||||
# if the identity provider is not found, redirect to the login page
|
# if the identity provider is not found, redirect to the login page
|
||||||
|
Loading…
x
Reference in New Issue
Block a user