source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/logout.py @ 3056

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/logout.py@3056
Revision 3056, 4.2 KB checked in by pjkersha, 13 years ago (diff)

Important fix for ticket #883 - ensures cookie at users login site is kept in sync with their Session Manager.

ows_server/ndgDiscovery.config: default SM URI goes through Apache now

ows_server/ows_server/controllers/login.py: added call to SessionMgr?.getSessionStatus in LoginController?.index. This checks the users session and if not found on the Session Manager, offers re-login. This is a likely scenario where the user logs off at a remote site removing their session from the Session Manager but leave stale security session cookie details on their home site.

ows_server/ows_server/lib/security_util.py: fix to LoginServiceQuery? - raise new LoginServiceQueryError? type exception

Line 
1from ows_server.lib.base import *
2from ows_server.lib.security_util import SecuritySession
3import logging
4log = logging.getLogger(__name__)
5
6from paste.request import parse_querystring
7import sys # include in case tracefile is set to sys.stderr
8import base64 # decode the return to address
9from urlparse import urlsplit, urlunsplit
10
11from ndg.security.common.SessionMgr import SessionMgrClient
12
13
14class LogoutController(BaseController):
15    '''Provides the pylons controller for logging out and killing the cookies
16    '''
17   
18    def __before__(self):
19        """Get return to URL"""
20        c.returnTo = request.params.get('r', '')
21       
22        # Check return to address - getCredentials should NOT be returned to
23        # with its query args intact
24        b64decReturnTo = base64.urlsafe_b64decode(c.returnTo)
25        scheme, netloc, pathInfo, query, frag = urlsplit(b64decReturnTo)
26        if 'getCredentials' in pathInfo:
27            # Swap to discovery and remove sensitive creds query args
28            #
29            # TODO: re-write to be more robust and modular.  Nb.
30            # BaseController.__call__ should filter out 'getCredentials'
31            # calls from c.requestURL so this code should never need to be
32            # executed.
33            filteredReturnTo = urlunsplit((scheme,netloc,'/discovery','',''))
34            c.returnTo = base64.urlsafe_b64encode(filteredReturnTo)
35
36   
37    def index(self):
38        ''' Ok, you really want to logout here '''
39
40        if 'ndgSec' not in session:
41            # There's no handle to a security session
42            log.error("logout called but no 'ndgSec' key in session object")
43            return self.__redirect()
44       
45        # Fixed URI to be equal to the session's security settings 'h' param!
46        # This contains the location of the Session Manager where the users
47        # session is held.
48        #
49        # Removed sslPeerCertCN setting here - the session manager could at
50        # any of a number of different trusted sites where the user logged in
51        # from.  There's no way of predicting an alternate SSL cert Common
52        # Name through the config file settings
53        #
54        # P J Kershaw 21/11/2007
55        try:
56            smClnt = SessionMgrClient(uri=session['ndgSec']['h'],
57                    sslCACertFilePathList=g.securityCfg.sslCACertFilePathList,
58                    signingCertFilePath=g.securityCfg.wssCertFilePath,
59                    signingPriKeyFilePath=g.securityCfg.wssPriKeyFilePath,
60                    signingPriKeyPwd=g.securityCfg.wssPriKeyPwd,
61                    caCertFilePathList=g.securityCfg.wssCACertFilePathList,
62                    tracefile=g.securityCfg.tracefile)       
63        except Exception, e:
64            log.error("logout - creating Session Manager client: %s" % e)
65            return self.__cleanupAndRedirect() 
66       
67        # Disconnect from Session Manager
68        log.info('Calling Session Manager "%s" disconnect for logout...' % \
69                 g.securityCfg.smURI)
70        try:
71            smClnt.disconnect(sessID=session['ndgSec']['sid'])
72        except Exception, e:
73            log.error("Error with Session Manager logout: %s" % e)
74            # don't exit here - instead proceed to delete session and
75            # redirect ...
76
77        return self.__cleanupAndRedirect()
78
79
80    def __cleanupAndRedirect(self):
81        """Remove security session and call _redirect"""
82        try:
83            # easy to kill our cookie
84            SecuritySession.delete()
85            if 'ndgCleared' in session: del session['ndgCleared']
86            session.save()
87           
88        except Exception, e:   
89            log.error("logout - clearing security session: %s" % e)
90
91        return self.__redirect()
92   
93   
94    def __redirect(self):
95        """Handle redirect back to previous page"""
96        if c.returnTo:
97            # Decode the return to address
98            try:
99                b64decReturnTo = base64.urlsafe_b64decode(c.returnTo)
100            except Exception, e:
101                log.error("logout - decoding return URL: %s" % e) 
102                return render_response('content')
103           
104            # and now go back to whence we had come
105            h.redirect_to(b64decReturnTo)
106        else:
107            return render_response('content')
Note: See TracBrowser for help on using the repository browser.