add logout support
This commit is contained in:
parent
957657972a
commit
565d7a07f2
1
README
1
README
|
@ -33,6 +33,7 @@ Add mellon urls to your urls::
|
|||
If SAML 2.0 should be your only authentication method you can define `mellon_login` as you main `LOGIN_URL`::
|
||||
|
||||
LOGIN_URL = 'mellon_login'
|
||||
LOGOUT_URL = 'mellon_logout'
|
||||
|
||||
Yout metadata will be downloadable through HTTP on
|
||||
|
||||
|
|
|
@ -111,3 +111,22 @@ def get_values(saml_attributes, name):
|
|||
|
||||
def get_parameter(idp, name):
|
||||
return idp.get(name) or getattr(app_settings, name)
|
||||
|
||||
def create_logout(request):
|
||||
server = create_server(request)
|
||||
mellon_session = request.session.get('mellon_session', {})
|
||||
entity_id = mellon_session.get('issuer')
|
||||
session_index = mellon_session.get('session_index')
|
||||
name_id_format = mellon_session.get('name_id_format')
|
||||
name_id_content = mellon_session.get('name_id_content')
|
||||
session_dump = render_to_string('mellon/session_dump.xml', {
|
||||
'entity_id': entity_id,
|
||||
'session_index': session_index,
|
||||
'name_id_format': name_id_format,
|
||||
'name_id_content': name_id_content,
|
||||
})
|
||||
logout = lasso.Logout(server)
|
||||
if not app_settings.PRIVATE_KEY:
|
||||
logout.setSignatureHint(lasso.PROFILE_SIGNATURE_HINT_FORBID)
|
||||
logout.setSessionFromDump(session_dump)
|
||||
return logout
|
||||
|
|
|
@ -5,7 +5,8 @@ from django.http import HttpResponseBadRequest, HttpResponseRedirect, HttpRespon
|
|||
from django.contrib import auth
|
||||
from django.conf import settings
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, redirect
|
||||
from django.utils.http import same_origin
|
||||
|
||||
import lasso
|
||||
|
||||
|
@ -120,10 +121,76 @@ class LoginView(View):
|
|||
login = csrf_exempt(LoginView.as_view())
|
||||
|
||||
class LogoutView(View):
|
||||
pass
|
||||
def get(self, request):
|
||||
if 'SAMLRequest' in request.GET:
|
||||
return self.idp_logout(request)
|
||||
elif 'SAMLResponse' in request.GET:
|
||||
return self.sp_logout_response(request)
|
||||
else:
|
||||
return self.sp_logout_request(request)
|
||||
|
||||
def idp_logout(self, request):
|
||||
'''Handle logout request emitted by the IdP'''
|
||||
logout = utils.create_logout(request)
|
||||
try:
|
||||
logout.processRequestMsg(request.META['QUERY_STRING'])
|
||||
except lasso.Error, e:
|
||||
return HttpResponseBadRequest('error processing logout request: %r' % e)
|
||||
try:
|
||||
logout.validateRequest()
|
||||
except lasso.Error, e:
|
||||
log.warning('error validating logout request: %r' % e)
|
||||
issuer = request.session.get('mellon_session', {}).get('issuer')
|
||||
if issuer == logout.remoteProviderId:
|
||||
auth.logout(request)
|
||||
try:
|
||||
logout.buildResponseMsg()
|
||||
except lasso.Error, e:
|
||||
return HttpResponseBadRequest('error processing logout request: %r' % e)
|
||||
return HttpResponseRedirect(logout.msgUrl)
|
||||
|
||||
def sp_logout_request(self, request):
|
||||
'''Launch a logout request to the identity provider'''
|
||||
next_url = request.GET.get('next') or settings.LOGIN_REDIRECT_URL
|
||||
referer = request.META.get('HTTP_REFERER')
|
||||
if not referer or same_origin(referer, request.build_absolute_uri()):
|
||||
if request.user.is_authenticated():
|
||||
issuer = request.session.get('mellon_session', {}).get('issuer')
|
||||
if issuer:
|
||||
logout = utils.create_logout(request)
|
||||
try:
|
||||
logout.initRequest(issuer, lasso.HTTP_METHOD_REDIRECT)
|
||||
logout.msgRelayState = next_url
|
||||
logout.buildRequestMsg()
|
||||
except lasso.Error, e:
|
||||
log.error('unable to initiate a logout request %r', e)
|
||||
else:
|
||||
return HttpResponseRedirect(logout.msgUrl)
|
||||
auth.logout(request)
|
||||
else:
|
||||
log.warning('logout refused referer %r is not of the '
|
||||
'same origin', referer)
|
||||
return HttpResponseRedirect(next_url)
|
||||
|
||||
def sp_logout_response(self, request):
|
||||
'''Launch a logout request to the identity provider'''
|
||||
if 'SAMLResponse' not in request.GET:
|
||||
return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
|
||||
logout = utils.create_logout(request)
|
||||
try:
|
||||
logout.processResponseMsg(request.GET['SAMLResponse'])
|
||||
except lasso.Error, e:
|
||||
log.error('unable to process a logout response %r', e)
|
||||
return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
|
||||
next_url = logout.msgRelayState
|
||||
if next_url and same_origin(next_url, request.build_absolute_uri()):
|
||||
return redirect(next_url)
|
||||
return redirect(settings.LOGIN_REDIRECT_URL)
|
||||
|
||||
|
||||
logout = LogoutView.as_view()
|
||||
|
||||
|
||||
def metadata(request):
|
||||
metadata = utils.create_metadata(request)
|
||||
return HttpResponse(metadata, content_type='text/xml')
|
||||
|
|
Loading…
Reference in New Issue