Add some logging and only permit backend CAS auth if the user is not already authenticated

This commit is contained in:
Valentin Samir 2016-07-04 22:54:15 +02:00
parent 624f2f48ed
commit 6b3b280d31
3 changed files with 31 additions and 2 deletions

View File

@ -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:

View File

@ -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

View File

@ -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")