Changeset 2867 for TI05-delivery


Ignore:
Timestamp:
31/08/07 17:27:51 (12 years ago)
Author:
pjkersha
Message:

ows_server/ows_server/models/ndgSecurity.py:

  • added logging for access decisions
  • updated hack for temporary AA address. This is in place until a permanent

address is allocated for the AA for CEDA and the Moles and CSML records
updated accordingly.

ows_server/ows_server/controllers/login.py:

  • fix in setup to the way c.returnTo is set - now uses request.paramsr?. - Previously 'r' was ignored if submitted as hidden filed in a form.
  • refactored code - simplified calls to SM connect and getAttCert in

getCredentials, added log debug messages to methods

ows_server/ows_server/controllers/logout.py:

  • added log messages.
  • check for 'ndgSec' is session object

ows_server/ows_server/templates/login.kid:

  • set 'r' as hidden field instead of query argument in form action string.

This to try as fix to #862 but suspect this may not be the root of the
problem.

Location:
TI05-delivery/ows_framework/trunk/ows_server/ows_server
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/login.py

    r2858 r2867  
    77from ows_common.exception_report import OwsError 
    88from paste.request import parse_querystring 
     9import logging 
     10log = logging.getLogger(__name__) 
    911 
    1012from ndg.security.common.AttAuthority import AttAuthorityClient 
    11 from ndg.security.common.SessionMgr import SessionMgrClient, \ 
     13from ndg.security.common.SessionMgr import SessionMgrClient, SessionExpired, \ 
    1214    AttributeRequestDenied 
    1315 
     
    1719     
    1820    def __setup(self): 
     21        """Get 'r' return to URL argument from current URL query string""" 
    1922        #where are we going back to? 
    20         self.inputs=dict(parse_querystring(request.environ)) 
    21         if 'r' in self.inputs: 
    22             c.returnTo=self.inputs['r'] 
    23         elif 'HTTP_REFERER' in request.environ: 
    24             #Added by Dom, 06/07/07 
    25             #http redirect  based on parse_querystring wasn't working so added this condition 
    26             #NOTE:  Not been able to test whether this has broken discovery/browse due to missing templates. 
    27             c.returnTo=request.environ['HTTP_REFERER'] 
     23#        self.inputs=dict(parse_querystring(request.environ)) 
     24#        if 'r' in self.inputs: 
     25#            c.returnTo=self.inputs['r'] 
     26#        elif 'HTTP_REFERER' in request.environ: 
     27#            #Added by Dom, 06/07/07 
     28#            #http redirect  based on parse_querystring wasn't working so added this condition 
     29#            #NOTE:  Not been able to test whether this has broken discovery/browse due to missing templates. 
     30#            c.returnTo=request.environ['HTTP_REFERER'] 
     31        # Try request.params - above method skips 'r' when passed in a hidden 
     32        # field in a HTTP POST 
     33        if 'r' in request.params: 
     34            c.returnTo = request.params['r'] 
    2835        else: 
    2936            c.returnTo='' 
     37             
    3038 
    3139    def __securitySetup(self): 
     
    7684        self.__setup() 
    7785        self.__securitySetup() 
    78          
    79         if not hasattr(self, "smClnt"): 
    80             smURI = self.ndgCfg.get('NDG_SECURITY', 'sessionMgrURI') 
    81  
    82             # May be better as a 'g' global set-up at start-up? 
    83             # 
    84             # tracefile could be removed for production use 
    85             self.smClnt = SessionMgrClient(uri=smURI, 
     86 
     87        smURI = self.ndgCfg.get('NDG_SECURITY', 'sessionMgrURI') 
     88 
     89        # May be better as a 'g' global set-up at start-up? 
     90        # 
     91        # tracefile could be removed for production use 
     92        smClnt = SessionMgrClient(uri=smURI, 
    8693                            sslCACertFilePathList=self.sslCACertFilePathList, 
    8794                            sslPeerCertCN=self.sslPeerCertCN, 
     
    96103         
    97104        # Connect to Session Manager 
    98         try: 
    99             proxyCert, proxyPriKey, userCert, sessID = \ 
    100                         self.smClnt.connect(username, passphrase=passphrase) 
     105        log.debug("Calling Session Manager connect for user ") 
     106        try: 
     107            sessID = smClnt.connect(username, passphrase=passphrase)[-1] 
    101108        except Exception, e: 
    102             c.xml = "Error logging in: %s" % e 
     109            c.xml = \ 
     110    "Error logging in.  Please check your username/pass-phrase and try again." 
     111            log.error("Session Manager connect returned: %s" % e) 
    103112            return render_response('login') 
    104113         
    105114        # Cache user attributes in Session Manager 
     115        log.debug("Calling Session Manager getAttCert for user ") 
    106116        try: 
    107117            # Set the Attribute Authority address for the Session Manager to 
     
    109119            aaURI = self.ndgCfg.get('NDG_SECURITY', 'attAuthorityURI') 
    110120 
    111             # Reset signature handler to authenticate client using user 
    112             # proxy cert returned from connect call 
    113             self.smClnt.signatureHandler.reqBinSecTokValType = 'X509PKIPathv1' 
    114             self.smClnt.signatureHandler.signingPriKey = proxyPriKey                
    115             wssCertChain = (userCert, proxyCert)     
    116             self.smClnt.signatureHandler.signingCertChain = wssCertChain 
    117  
    118121            # Make request for attribute certificate 
    119             attCert = self.smClnt.getAttCert(attAuthorityURI=aaURI) 
    120  
     122            attCert = smClnt.getAttCert(sessID=sessID, attAuthorityURI=aaURI) 
     123        except SessionExpired, e: 
     124            log.info("Session expired getting Attribute Certificate: %s" % e) 
     125            c.xml = "Session has expired, please re-login" 
     126            render_response('login') 
     127             
    121128        except AttributeRequestDenied, e: 
    122             c.xml = "No roles available: %s" % e 
     129            log.error("Login: attribute Certificate request denied: %s" % e) 
     130            c.xml = "No authorisation roles are available for your " + \ 
     131                    "account.  Please check with your site administrator." 
    123132            return render_response('login') 
    124133             
    125134        except Exception, e: 
    126             c.xml = "Error getting roles: %s" % e 
     135            log.error("Login: attribute Certificate request: %s" % e) 
     136            c.xml = "An internal error occured.  Please report this to " + \ 
     137                    "your site administrator." 
    127138            return render_response('login') 
    128139 
     
    139150        self.__doRedirect() 
    140151             
     152             
    141153    def wayf(self): 
    142154        ''' NDG equivalent to Shibboleth WAYF ''' 
     
    144156        self.__setup() 
    145157        self.__securitySetup() 
    146  
    147         # TODO: check with Bryan what this is for 
    148         # P J Kershaw 09/08/07 
    149         if 'roleNeeded' in self.inputs: 
    150              
    151             # should ask the attribute authority what hosts to put up for login 
    152             # but meanwhile we'll fudge it 
    153             pass 
    154          
    155         if not hasattr(self, "aaClnt"): 
    156             aaURI = self.ndgCfg.get('NDG_SECURITY', 'attAuthorityURI') 
    157  
    158             # May be better as a 'g' global set-up at start-up? 
    159             # 
    160             # tracefile could be removed for production use 
    161             self.aaClnt = AttAuthorityClient(uri=aaURI, 
     158         
     159        aaURI = self.ndgCfg.get('NDG_SECURITY', 'attAuthorityURI') 
     160 
     161        # May be better as a 'g' global set-up at start-up? 
     162        # 
     163        # tracefile could be removed for production use 
     164        aaClnt = AttAuthorityClient(uri=aaURI, 
    162165                                signingCertFilePath=self.wssCertFilePath, 
    163166                                signingPriKeyFilePath=self.wssPriKeyFilePath, 
     
    167170 
    168171        # Get list of login uris for trusted sites including THIS one 
    169         trustedHosts = self.aaClnt.getTrustedHostInfo() 
    170         thisHost = self.aaClnt.getHostInfo() 
     172        log.debug("Calling Attribute Authority getTrustedHostInfo and " + \ 
     173                  "getHostInfo for wayf") 
     174        trustedHosts = aaClnt.getTrustedHostInfo() 
     175        thisHost = aaClnt.getHostInfo() 
    171176         
    172177        try: 
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/logout.py

    r2858 r2867  
    11from ows_server.lib.base import * 
    22from ows_server.lib.security_util import SecuritySession 
     3import logging 
     4log = logging.getLogger(__name__) 
    35 
    46from paste.request import parse_querystring 
     
    6163        self.__setup() 
    6264 
     65        if 'ndgSec' not in session: 
     66            # There's no handle to a security session 
     67            log.info("logout called but no 'ndgSec' key in session object") 
     68            return render_response('content') 
     69         
    6370        # Look into the session and go kill the wallet 
    64         if not hasattr(self, "smClnt"): 
    65             smURI = self.ndgCfg.get('NDG_SECURITY', 'sessionMgrURI') 
     71        smURI = self.ndgCfg.get('NDG_SECURITY', 'sessionMgrURI') 
    6672 
    67             # May be better as a 'g' global set-up at start-up? 
    68             # 
    69             # tracefile could be removed for production use 
    70             self.smClnt = SessionMgrClient(uri=smURI, 
     73        # May be better as a 'g' global set-up at start-up? 
     74        # 
     75        # tracefile could be removed for production use 
     76        smClnt = SessionMgrClient(uri=smURI, 
    7177                            sslCACertFilePathList=self.sslCACertFilePathList, 
    7278                            sslPeerCertCN=self.sslPeerCertCN, 
     
    7884             
    7985        # Disconnect from Session Manager 
     86        log.info("Calling Session Manager disconnect for logout") 
    8087        try: 
    81             self.smClnt.disconnect(sessID=session['ndgSec']['sid']) 
    82         except Exception, e: 
    83             c.xml = "Error disconnecting: %s" % e 
    84          
    85         # easy to kill our cookie 
    86         SecuritySession.delete() 
    87         if 'ndgCleared' in session: del session['ndgCleared'] 
    88          
    89         session.save() 
    90  
    91         # Decode the return to address 
    92         b64decReturnTo = base64.urlsafe_b64decode(c.returnTo) 
    93         
    94         # and now go back to whence we had come 
    95         h.redirect_to(b64decReturnTo) 
     88            try: 
     89                smClnt.disconnect(sessID=session['ndgSec']['sid']) 
     90            except Exception, e: 
     91                log.error("Error with Session Manager logout: %s" % e) 
     92        finally: 
     93            # easy to kill our cookie 
     94            SecuritySession.delete() 
     95            if 'ndgCleared' in session: del session['ndgCleared'] 
     96             
     97            session.save() 
     98     
     99            if c.returnTo: 
     100                # Decode the return to address 
     101                b64decReturnTo = base64.urlsafe_b64decode(c.returnTo) 
     102                
     103                # and now go back to whence we had come 
     104                h.redirect_to(b64decReturnTo) 
     105            else: 
     106                return render_response('content') 
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/models/ndgSecurity.py

    r2803 r2867  
    22 
    33from pylons import request 
     4import logging 
     5log = logging.getLogger(__name__) 
    46 
    57from ows_common.exception_report import OwsError 
     
    1214    return SecurityHandler(securityElement, securityTokens)() 
    1315 
    14 # This is an initial implementation and is untested.  See TODOs 
    15 # for more info 
    16 # 
    17 # P J Kershaw 26/07/07 
     16 
    1817class SecurityHandler(object): 
    1918    """Make access control decision based on CSML constraint and user security 
     
    2120     
    2221    AccessAllowedMsg = "Access Allowed" 
    23     AccessDeniedMsg = "Access Denied" 
     22    InvalidAttributeCertificate = \ 
     23            "The certificate containing your authorisation roles is invalid" 
    2424    NotLoggedInMsg = 'Not Logged in' 
    2525    SessionExpiredMsg = 'Session has expired.  Please re-login' 
    2626    InvalidSessionMsg = 'Session is invalid.  Please try re-login' 
     27    InvalidSecurityCondition = 'Invalid Security Condition' 
    2728 
    2829    def __init__(self, securityElement, securityTokens): 
     
    7071            self.wssPriKeyPwd = self.ndgCfg.get('NDG_SECURITY',m)     
    7172            m='wssCACertFilePathList' 
    72             self.wssCACertFilePathList =self.ndgCfg.get('NDG_SECURITY',m).split() 
     73            self.wssCACertFilePathList=self.ndgCfg.get('NDG_SECURITY',m).split() 
    7374             
    7475            # Attribute Certificate verification of X.509 cert chain back to CA 
     
    106107        @keyword securityTokens: dict-like session object containing security  
    107108        tokens.  Resets equivalent object attribute.""" 
     109           
     110        # tokens and element may be set from __init__ or as args to this  
     111        # method.  If the latter copy them into self   
     112        if securityTokens: 
     113            self.securityTokens = securityTokens 
     114                             
     115        if securityElement: 
     116            self.securityElement=securityElement 
    108117      
    109118        # Check self.securityTokens - if not set then the user mustn't be  
     
    119128            # discovery page? 
    120129            # P J Kershaw 10/08/07 
     130            log.info("Exiting from Gatekeeper: user is not logged in") 
    121131            return False, self.__class__.NotLoggedInMsg 
    122  
     132             
     133        xpathr='{http://ndg.nerc.ac.uk/moles}simpleCondition/{http://ndg.nerc.ac.uk/moles}attrauthRole' 
     134        xpathaa='{http://ndg.nerc.ac.uk/moles}simpleCondition/{http://ndg.nerc.ac.uk/moles}dgAttributeAuthority' 
     135        roleE,aaE=self.securityElement.find(xpathr),self.securityElement.find(xpathaa) 
     136        if None in (roleE,aaE): 
     137            log.info("Gatekeeper: Role and/or Attribute Authority URI " + \ 
     138                     "not found in dataset element: %s" % securityElement) 
     139            return False, self.__class__.InvalidSecurityCondition 
     140         
     141        self.reqRole=roleE.text 
     142        self.reqAAURI=aaE.text 
     143 
     144        # TODO: get rid of this horrible hack when permanent BADC Attribute 
     145        # Authority address is established. 
     146        # P J Kershaw 31/08/07 
     147        badcTestAAURI = \ 
     148        "http://glue.badc.rl.ac.uk/services/ndg/security/AttributeAuthority" 
     149        try: 
     150            # Dumb test to see if URI is correct 
     151            import urllib 
     152            fp=urllib.urlopen(self.reqAAURI) 
     153            if "404 Not Found" in fp.read(): 
     154                self.reqAAURI = badcTestAAURI 
     155        except: 
     156            self.reqAAURI = badcTestAAURI 
     157     
    123158        # Create Session Manager client 
    124159        self.smClnt = SessionMgrClient(uri=self.securityTokens['h'], 
     
    130165                            caCertFilePathList=self.wssCACertFilePathList, 
    131166                            tracefile=self.tracefile)        
    132                              
    133         if securityElement: 
    134             self.securityElement=securityElement 
    135              
    136         xpathr='{http://ndg.nerc.ac.uk/moles}simpleCondition/{http://ndg.nerc.ac.uk/moles}attrauthRole' 
    137         xpathaa='{http://ndg.nerc.ac.uk/moles}simpleCondition/{http://ndg.nerc.ac.uk/moles}dgAttributeAuthority' 
    138         roleE,aaE=self.securityElement.find(xpathr),self.securityElement.find(xpathaa) 
    139         if None in (roleE,aaE): 
    140             return True,'Invalid Security Condition' 
    141         self.reqRole=roleE.text 
    142         self.reqAAURI=aaE.text 
    143              
    144         if securityTokens: 
    145             self.securityTokens = securityTokens 
    146          
    147         if not self.securityTokens: 
    148             return False, self.__class__.NotLoggedInMsg 
    149         else: 
    150             return self.__checkAttCert() 
     167         
     168        return self.__checkAttCert() 
    151169             
    152170 
     
    158176             
    159177        try: 
    160  
    161178            # Make request for attribute certificate 
    162179            # 
     
    167184            self.reqAAURI="http://glue.badc.rl.ac.uk/services/ndg/security/AttributeAuthority" 
    168185            attCert = self.smClnt.getAttCert(attAuthorityURI=self.reqAAURI, 
    169                                      sessID=self.securityTokens['sid'], 
    170                                      reqRole=self.reqRole) 
    171  
     186                                         sessID=self.securityTokens['sid'], 
     187                                         reqRole=self.reqRole) 
    172188        except AttributeRequestDenied, e: 
    173             # TODO: write exception to log 
     189            log.info("Gatekeeper - access denied: %s" % e) 
    174190            return False, str(e) 
    175191         
     
    177193            # Clear the security details from the session object 
    178194            SecuritySession.delete() 
     195            log.info("Gatekeeper - access denied: %s" % e) 
    179196            return False, self.__class__.NotLoggedInMsg 
    180197 
     
    182199            # Clear the security details from the session object 
    183200            SecuritySession.delete() 
     201            log.info("Gatekeeper - access denied: %s" % e) 
    184202            return False, self.__class__.SessionExpiredMsg 
    185203 
     
    187205            # Clear the security details from the session object 
    188206            SecuritySession.delete() 
     207            log.info("Gatekeeper - access denied: %s" % e) 
    189208            return False, self.__class__.InvalidSessionMsg 
    190209             
    191210        except InvalidSession, e: 
    192211            SecuritySession.delete() 
     212            log.info("Gatekeeper - access denied: %s" % e) 
    193213            return False, self.__class__.InvalidSessionMsg 
    194214 
     
    203223        # Check it's issuer is as expected 
    204224        if attCert.issuer != self.acIssuer: 
    205             raise OwsError, \ 
    206                 'Attribute Certificate issuer DN, "%s"' % attCert.issuer + \ 
     225            log.info('Gatekeeper - access denied: Attribute Certificate ' + \ 
     226                'issuer DN, "%s"' % attCert.issuer + \ 
    207227                'must match this data provider\'s Attribute Authority ' + \ 
    208                 'DN: "%s"' % self.acIssuer 
    209                         
     228                'DN: "%s"' % self.acIssuer) 
     229            return False, self.__class__.InvalidAttributeCertificate 
     230         
     231        log.info('Gatekeeper: access granted for user "%s" to "%s" ' % \ 
     232                 (attCert.userId, self.securityElement) + \ 
     233                 'with attribute certificate:\n\n%s' % attCert)   
     234                      
    210235        return True, self.__class__.AccessAllowedMsg 
    211236         
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/templates/login.kid

    r2858 r2867  
    1818     
    1919    <span py:def="loginForm()" class="loginForm"> 
    20                 <form action="$g.getCredentials?r=${c.returnTo}" method="POST">     
     20                <form action="$g.getCredentials" method="POST"> 
     21                <input type="hidden" name="r" value="${c.returnTo}"/> 
    2122                <table cellspacing="0" border="0" cellpadding="5"> 
    2223                <tbody> 
Note: See TracChangeset for help on using the changeset viewer.