source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/zsi/sessionmanager/__init__.py @ 4692

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/zsi/sessionmanager/__init__.py@4692
Revision 4692, 9.4 KB checked in by pjkersha, 11 years ago (diff)

Refactoring of SSO service to enable use of local AA and SM instances via keys to environ.

Line 
1"""ZSI Server side SOAP Binding for Session Manager Web Service
2
3NERC Data Grid Project"""
4__author__ = "P J Kershaw"
5__date__ = "01/10/08"
6__copyright__ = "(C) 2008 STFC"
7__license__ = \
8"""This software may be distributed under the terms of the Q Public
9License, version 1.0 or later."""
10__contact__ = "Philip.Kershaw@stfc.ac.uk"
11__revision__ = '$Id$'
12import os, sys
13import base64
14import logging
15log = logging.getLogger(__name__)
16
17
18from ndg.security.server.zsi.sessionmanager.SessionManager_services_server \
19    import SessionManagerService as _SessionManagerService
20from ndg.security.common.zsi.sessionmanager.SessionManager_services import \
21    connectInputMsg, disconnectInputMsg, getSessionStatusInputMsg, \
22    getAttCertInputMsg
23   
24   
25from ndg.security.server.sessionmanager import SessionManager
26from ndg.security.common.credentialwallet import \
27                                        CredentialWalletAttributeRequestDenied 
28from ndg.security.common.wssecurity.dom import SignatureHandler
29from ndg.security.common.X509 import X509Cert, X509CertRead
30
31class SessionManagerWSConfigError(Exception):
32    '''Raise for errors related to the Session Manager Web Service
33    configuration'''
34   
35class SessionManagerWS(_SessionManagerService):
36    '''Session Manager ZSI SOAP Service Binding class'''
37   
38    def __init__(self, **kw):
39       
40        # Stop in debugger at beginning of SOAP stub if environment variable
41        # is set
42        self.__debug = bool(os.environ.get('NDGSEC_INT_DEBUG'))
43        if self.__debug:
44            import pdb
45            pdb.set_trace()
46       
47        # Extract local Attribute Authority environ identifier
48        self.attributeAuthorityFilterID = kw.pop('attributeAuthorityFilterID', 
49                                                 None)
50        if self.attributeAuthorityFilterID is None:
51            log.warning('No "attributeAuthorityFilterID" option was '
52                        'set in the input config: link to a local Attibute '
53                        'Authority instance is disabled')
54       
55        # ... and WS-Security signature verification filter
56        self.wsseSignatureVerificationFilterID = kw.pop(
57                                        'wsseSignatureVerificationFilterID', 
58                                        None)
59        if self.wsseSignatureVerificationFilterID is None:
60            log.warning('No "wsseSignatureVerificationFilterID" option was '
61                        'set in the input config')
62       
63        # Initialise Attribute Authority class - property file will be
64        # picked up from default location under $NDG_DIR directory
65        self.sm = SessionManager(**kw)
66
67
68    def soap_connect(self, ps):
69        '''Connect to Session Manager and create a user session
70       
71        @type ps: ZSI ParsedSoap
72        @param ps: client SOAP message
73        @rtype: tuple
74        @return: request and response objects'''
75
76        if self.__debug:
77            import pdb
78            pdb.set_trace()
79           
80        request = ps.Parse(connectInputMsg.typecode)   
81        response = _SessionManagerService.soap_connect(self, ps)
82       
83        result = self.sm.connect(username=request.Username,
84                                 passphrase=request.Passphrase,
85                                 createServerSess=request.CreateServerSess)
86                   
87        response.UserX509Cert, response.UserPriKey, response.issuingCert, \
88            response.SessID = result
89                 
90        return response
91
92
93    def soap_disconnect(self, ps):
94        '''Disconnect and remove user's session
95       
96        @type ps: ZSI ParsedSoap
97        @param ps: client SOAP message
98        @rtype: tuple
99        @return: request and response objects'''
100        if self.__debug:
101            import pdb
102            pdb.set_trace()
103           
104        request = ps.Parse(disconnectInputMsg.typecode)             
105        response = _SessionManagerService.soap_disconnect(self, ps)
106       
107        # Derive designated user ID differently according to whether
108        # a session ID was passed and the message was signed
109        sessID = request.SessID or None
110           
111        # Derive designated holder X.509 cert differently according to whether
112        # a signed message is expected from the client - NB, this is dependent
113        # on whether a reference to the signature filter was set in the
114        # environment
115        signatureFilter = self.referencedWSGIFilters.get(
116                                        self.wsseSignatureVerificationFilterID)
117        if signatureFilter is not None:
118            # Get certificate corresponding to private key that signed the
119            # message - i.e. the user's certificate
120            log.debug("Reading holder certificate from WS-Security "
121                      "signature header")
122            userX509Cert = signatureFilter.signatureHandler.verifyingCert
123        else:
124            # No signature from client - they must instead provide the
125            # designated holder cert via the UserX509Cert input
126            log.debug('Reading holder certificate from SOAP "userX509Cert" '
127                      'parameter')
128            userX509Cert = request.UserX509Cert
129           
130        self.sm.deleteUserSession(sessID=sessID, userX509Cert=userX509Cert)
131        return response
132
133
134    def soap_getSessionStatus(self, ps):
135        '''Check for existence of a session with given session ID or user
136        Distinguished Name
137       
138        @type ps: ZSI ParsedSoap
139        @param ps: client SOAP message
140        @rtype: tuple
141        @return: request and response objects'''
142
143        if self.__debug:
144            import pdb
145            pdb.set_trace()
146           
147        request = ps.Parse(getSessionStatusInputMsg.typecode)             
148        response = _SessionManagerService.soap_getSessionStatus(self, ps)
149       
150        response.IsAlive = self.sm.getSessionStatus(userDN=request.UserDN,
151                                                    sessID=request.SessID)
152                 
153        return response
154
155
156    def soap_getAttCert(self, ps):
157        '''Get Attribute Certificate from a given Attribute Authority
158        and cache it in user's Credential Wallet
159       
160        @type ps: ZSI ParsedSoap
161        @param ps: client SOAP message
162        @rtype: tuple
163        @return: request and response objects'''
164        if self.__debug:
165            import pdb
166            pdb.set_trace()
167           
168        request = ps.Parse(getAttCertInputMsg.typecode)             
169        response = _SessionManagerService.soap_getAttCert(self, ps)
170
171        # Derive designated holder X.509 cert. differently according to whether
172        # a signed message is expected from the client - NB, this is dependent
173        # on whether a reference to the signature filter was set in the
174        # environment
175        signatureFilter = self.referencedWSGIFilters.get(
176                                        self.wsseSignatureVerificationFilterID)
177        if signatureFilter is not None:
178            # Get certificate corresponding to private key that signed the
179            # message - i.e. the user's proxy
180            log.debug("Reading holder certificate from WS-Security "
181                      "signature header")
182            userX509Cert = signatureFilter.signatureHandler.verifyingCert
183        else:
184            # No signature from client - they must instead provide the
185            # designated holder cert via the UserX509Cert input
186            log.debug('Reading holder certificate from SOAP "userX509Cert" '
187                      'parameter')
188            userX509Cert = request.UserX509Cert
189
190        # If no Attribute Authority URI is set pick up local Attribute
191        # instance Authority
192        if request.AttributeAuthorityURI is None:
193            attributeAuthorityFilter = \
194                self.referencedWSGIFilters.get(self.attributeAuthorityFilterID)
195               
196            try:
197                attributeAuthority= \
198                                attributeAuthorityFilter.serviceSOAPBinding.aa
199            except AttributeError, e:
200                raise SessionManagerWSConfigError("No Attribute Authority URI "
201                        "was input and no Attribute Authority instance "
202                        "reference set in environ: %s" % e)
203        else:
204            attributeAuthority = None
205               
206        # X.509 Cert used in signature is preferred over userX509Cert input
207        # element - userX509Cert may have been omitted.
208        try:
209            attCert = self.sm.getAttCert(
210                            userX509Cert=userX509Cert or request.UserX509Cert,
211                            sessID=request.SessID,
212                            attributeAuthorityURI=request.AttributeAuthorityURI,
213                            attributeAuthority=attributeAuthority,
214                            reqRole=request.ReqRole,
215                            mapFromTrustedHosts=request.MapFromTrustedHosts,
216                            rtnExtAttCertList=request.RtnExtAttCertList,
217                            extAttCertList=request.ExtAttCert,
218                            extTrustedHostList=request.ExtTrustedHost)
219            response.AttCert = attCert.toString() 
220           
221        except CredentialWalletAttributeRequestDenied, e:
222            # Exception object contains a list of attribute certificates
223            # which could be used to re-try to get authorisation via a mapped
224            # certificate
225            response.Msg = str(e)
226            response.ExtAttCertOut = e.extAttCertList
227       
228        return response
Note: See TracBrowser for help on using the repository browser.