source: TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/authz/pep.py @ 7168

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/authz/pep.py@7168
Revision 7168, 7.1 KB checked in by pjkersha, 9 years ago (diff)

Incomplete - task 2: XACML-Security Integration

  • testing ndg.security.server.wsgi.authz.pep.SamlPepMiddleware? in ndg.security.test.unit.authz.test_authz
Line 
1'''
2Created on 11 Jul 2010
3
4@author: pjkersha
5'''
6from webob import Request
7
8from ndg.saml.saml2.binding.soap.client.authzdecisionquery import \
9                                            AuthzDecisionQuerySslSOAPBinding
10from ndg.security.server.wsgi.session import SessionHandlerMiddleware
11
12
13class SamlPepMiddlewareConfigError(Exception):
14    """Error with SAML PEP configuration settings"""
15   
16   
17class SamlPepMiddleware(object):
18    '''Policy Enforcement Point for ESG with SAML based Interface
19   
20    @requires: ndg.security.server.wsgi.session.SessionHandlerMiddleware
21    instance upstream in the WSGI stack.
22   
23    @cvar AUTHZ_DECISION_QUERY_PARAMS_PREFIX: prefix for SAML authorisation
24    decision query options in config file
25    @type AUTHZ_DECISION_QUERY_PARAMS_PREFIX: string
26   
27    @cvar PARAM_NAMES: list of config option names
28    @type PARAM_NAMES: tuple
29   
30    @ivar __client: SAML authorisation decision query client
31    @type __client: ndg.saml.saml2.binding.soap.client.authzdecisionquery.AuthzDecisionQuerySslSOAPBinding
32    '''
33    AUTHZ_DECISION_QUERY_PARAMS_PREFIX = 'authzDecisionQuery.'
34    SESSION_KEY_PARAM_NAME = 'sessionKey'
35   
36    CREDENTIAL_WALLET_SESSION_KEYNAME = \
37        SessionHandlerMiddleware.CREDENTIAL_WALLET_SESSION_KEYNAME
38    USERNAME_SESSION_KEYNAME = \
39        SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME
40   
41    PARAM_NAMES = (
42        'authzServiceURI',
43        'sessionKey'
44    )
45    __slots__ = (
46        '_app', '__client', '__session',
47    ) + tuple(["__%s" % i for i in PARAM_NAMES])
48    del i
49   
50    def __init__(self, app):
51        '''
52        Add reference to next WSGI middleware/app and create a SAML
53        authorisation decision query client interface
54        '''
55        self._app = app
56        self.__client = AuthzDecisionQuerySslSOAPBinding()
57        self.__session = None
58        self.__authzServiceURI = None
59        self.__sessionKey = None
60
61    def _getClient(self):
62        return self.__client
63
64    def _setClient(self, value):
65        if not isinstance(value, basestring):
66            raise TypeError('Expecting string type for "client" attribute; '
67                            'got %r' % type(value))
68        self.__client = value
69
70    client = property(_getClient, _setClient, 
71                      doc="SAML authorisation decision query SOAP client")
72
73    def _getSession(self):
74        return self.__session
75
76    def _setSession(self, value):
77        self.__session = value
78
79    session = property(_getSession, _setSession, 
80                       doc="Beaker Security Session instance")
81
82    def _getAuthzServiceURI(self):
83        return self.__authzServiceURI
84
85    def _setAuthzServiceURI(self, value):
86        if not isinstance(value, basestring):
87            raise TypeError('Expecting string type for "authzServiceURI" '
88                            'attribute; got %r' % type(value))
89        self.__authzServiceURI = value
90
91    authzServiceURI = property(_getAuthzServiceURI, _setAuthzServiceURI, 
92                               doc="Authorisation Service URI")
93
94    def _getSessionKey(self):
95        return self.__sessionKey
96
97    def _setSessionKey(self, value):
98        if not isinstance(value, basestring):
99            raise TypeError('Expecting string type for "sessionKey" attribute; '
100                            'got %r' % type(value))
101        self.__sessionKey = value
102
103    sessionKey = property(_getSessionKey, _setSessionKey, 
104                          doc="environ key name for Beaker session object")
105
106    def initialise(self, prefix='', **kw):
107        '''Initialise object from keyword settings
108       
109        @type prefix: basestring
110        @param prefix: prefix for configuration items
111        @type kw: dict       
112        @param kw: configuration settings
113        dictionary
114        @raise SamlPepMiddlewareConfigError: missing option setting(s)
115        '''
116        # Parse authorisation decision query options
117        queryPrefix = prefix + self.__class__.AUTHZ_DECISION_QUERY_PARAMS_PREFIX
118        self.client.parseKeywords(prefix=queryPrefix, **kw)
119           
120        # Parse other options
121        for name in SamlPepMiddleware.PARAM_NAMES:
122            paramName = prefix + name
123            value = kw.get(paramName)
124            if value is None:
125                raise SamlPepMiddlewareConfigError('Missing option %r' % 
126                                                   paramName)
127            setattr(self, name, value)
128                   
129    @classmethod
130    def filter_app_factory(cls, app, global_conf, prefix='', **app_conf):
131        """Set-up using a Paste app factory pattern. 
132       
133        @type app: callable following WSGI interface
134        @param app: next middleware application in the chain     
135        @type global_conf: dict       
136        @param global_conf: PasteDeploy global configuration dictionary
137        @type prefix: basestring
138        @param prefix: prefix for configuration items
139        @type app_conf: dict       
140        @param app_conf: PasteDeploy application specific configuration
141        dictionary
142        """
143        app = cls(app)
144        app.initialise(prefix=prefix, **app_conf)
145       
146        return app
147               
148    def __call__(self, environ, start_response):
149        """Intercept request and call authorisation service to make an access
150        control decision
151       
152        @type environ: dict
153        @param environ: WSGI environment variables dictionary
154        @type start_response: function
155        @param start_response: standard WSGI start response function
156        @rtype: iterable
157        @return: response
158        """
159        # Get reference to session object - SessionHandler middleware must be in
160        # place upstream of this middleware in the WSGI stack
161        if self.sessionKey not in environ:
162            raise SamlPepMiddlewareConfigError('No beaker session key "%s" '
163                                               'found in environ' % 
164                                               self.sessionKey)
165        self.session = environ[self.sessionKey]
166       
167        request = Request(environ)
168        self.__client.resourceURI = request.url
169        self.__client.subjectID = request.remote_user or ''
170       
171        self.__client.send(uri=self.__authzServiceURI)
172       
173        return self._app(environ, start_response)
174
175    def _createAuthzDecisionQuery(self,
176                                  resourceURI, 
177                            subject):
178        """Create SAML authorisation decision query object ready for dispatch
179        """
180#        query = AuthzDecisionQuery()
181#        query.version = SAMLVersion(SAMLVersion.VERSION_20)
182#        query.id = str(uuid4())
183#        query.issueInstant = datetime.utcnow()
184#       
185#        query.issuer = Issuer()
186#        query.issuer.format = Issuer.X509_SUBJECT
187#        query.issuer.value = issuer
188#                       
189#        query.subject = Subject() 
190#        query.subject.nameID = NameID()
191#        query.subject.nameID.format = "urn:ndg:saml:test:openid"
192#        query.subject.nameID.value = subject
193#   
194#        query.resource = resource
195#                 
196#        query.actions.append(Action())
197#        query.actions[0].namespace = actionNs
198#        query.actions[0].value = action   
199#
200#        return query       
Note: See TracBrowser for help on using the repository browser.