Add some logging and only permit backend CAS auth if the user is not already authenticated
This commit is contained in:
parent
624f2f48ed
commit
6b3b280d31
3 changed files with 31 additions and 2 deletions
|
@ -16,11 +16,14 @@ from django.db import IntegrityError
|
||||||
from .cas import CASClient
|
from .cas import CASClient
|
||||||
from .models import FederatedUser, FederateSLO, User
|
from .models import FederatedUser, FederateSLO, User
|
||||||
|
|
||||||
|
import logging
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from six.moves import urllib
|
from six.moves import urllib
|
||||||
|
|
||||||
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
|
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CASFederateValidateUser(object):
|
class CASFederateValidateUser(object):
|
||||||
"""Class CAS client used to authenticate the user again a CAS provider"""
|
"""Class CAS client used to authenticate the user again a CAS provider"""
|
||||||
|
@ -88,6 +91,12 @@ class CASFederateValidateUser(object):
|
||||||
slos = []
|
slos = []
|
||||||
for slo in slos:
|
for slo in slos:
|
||||||
for federate_slo in FederateSLO.objects.filter(ticket=slo.text):
|
for federate_slo in FederateSLO.objects.filter(ticket=slo.text):
|
||||||
|
logger.info(
|
||||||
|
"Got an SLO requests for ticket %s, logging out user %s" % (
|
||||||
|
federate_slo.username,
|
||||||
|
federate_slo.ticket
|
||||||
|
)
|
||||||
|
)
|
||||||
session = SessionStore(session_key=federate_slo.session_key)
|
session = SessionStore(session_key=federate_slo.session_key)
|
||||||
session.flush()
|
session.flush()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -228,11 +228,12 @@ class CanLogin(object):
|
||||||
self.assertEqual(response.status_code, code)
|
self.assertEqual(response.status_code, code)
|
||||||
# this message is displayed to the user upon successful authentication, so it should not
|
# this message is displayed to the user upon successful authentication, so it should not
|
||||||
# appear
|
# appear
|
||||||
self.assertFalse(
|
self.assertNotIn(
|
||||||
(
|
(
|
||||||
b"You have successfully logged into "
|
b"You have successfully logged into "
|
||||||
b"the Central Authentication Service"
|
b"the Central Authentication Service"
|
||||||
) in response.content
|
),
|
||||||
|
response.content
|
||||||
)
|
)
|
||||||
|
|
||||||
# if authentication has failed, these session variables should not be set
|
# if authentication has failed, these session variables should not be set
|
||||||
|
|
|
@ -208,6 +208,7 @@ class FederateAuth(View):
|
||||||
def post(self, request, provider=None):
|
def post(self, request, provider=None):
|
||||||
"""method called on POST request"""
|
"""method called on POST request"""
|
||||||
if not settings.CAS_FEDERATE:
|
if not settings.CAS_FEDERATE:
|
||||||
|
logger.warning("CAS_FEDERATE is False, set it to True to use the federated mode")
|
||||||
return redirect("cas_server:login")
|
return redirect("cas_server:login")
|
||||||
# POST with a provider, this is probably an SLO request
|
# POST with a provider, this is probably an SLO request
|
||||||
try:
|
try:
|
||||||
|
@ -251,15 +252,26 @@ class FederateAuth(View):
|
||||||
def get(self, request, provider=None):
|
def get(self, request, provider=None):
|
||||||
"""method called on GET request"""
|
"""method called on GET request"""
|
||||||
if not settings.CAS_FEDERATE:
|
if not settings.CAS_FEDERATE:
|
||||||
|
logger.warning("CAS_FEDERATE is False, set it to True to use the federated mode")
|
||||||
|
return redirect("cas_server:login")
|
||||||
|
if self.request.session.get("authenticated"):
|
||||||
|
logger.warning("User already authenticated, dropping federate authentication request")
|
||||||
return redirect("cas_server:login")
|
return redirect("cas_server:login")
|
||||||
try:
|
try:
|
||||||
provider = FederatedIendityProvider.objects.get(suffix=provider)
|
provider = FederatedIendityProvider.objects.get(suffix=provider)
|
||||||
auth = self.get_cas_client(request, provider)
|
auth = self.get_cas_client(request, provider)
|
||||||
if 'ticket' not in request.GET:
|
if 'ticket' not in request.GET:
|
||||||
|
logger.info("Trying to authenticate again %s" % auth.provider.server_url)
|
||||||
return HttpResponseRedirect(auth.get_login_url())
|
return HttpResponseRedirect(auth.get_login_url())
|
||||||
else:
|
else:
|
||||||
ticket = request.GET['ticket']
|
ticket = request.GET['ticket']
|
||||||
if auth.verify_ticket(ticket):
|
if auth.verify_ticket(ticket):
|
||||||
|
logger.info(
|
||||||
|
"Got a valid ticket for %s from %s" % (
|
||||||
|
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
|
||||||
|
@ -267,8 +279,15 @@ class FederateAuth(View):
|
||||||
url = utils.reverse_params("cas_server:login", params)
|
url = utils.reverse_params("cas_server:login", params)
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
else:
|
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())
|
return HttpResponseRedirect(auth.get_login_url())
|
||||||
except FederatedIendityProvider.DoesNotExist:
|
except FederatedIendityProvider.DoesNotExist:
|
||||||
|
logger.warning("Identity provider suffix %s not found" % provider)
|
||||||
return redirect("cas_server:login")
|
return redirect("cas_server:login")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue