source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/security_util.py @ 2949

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

Makefile: fixed install target

ows_server/ows_server/models/ndgSecurity.py:

  • include ows_server.lib.base import to enable refs to 'g' global.
  • fixed g.securityCfg.acCACertFilePathList and g.securityCfg.acIssuer var refs

ows_server/ows_server/lib/security_util.py:

Line 
1# Copyright (C) 2007 STFC & NERC (Science and Technology Facilities Council).
2# This software may be distributed under the terms of the
3# Q Public License, version 1.0 or later.
4# http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
5"""
6Utilities for transfor of credentials over login service
7
8@author: Philip Kershaw
9"""
10__revision__ = '$Id:$'
11
12import logging
13log = logging.getLogger(__name__)
14
15from pylons import session, request
16
17
18class SecuritySession(object):
19    """Utility for Pylons security session keys enables correct
20    keys to be set
21   
22    @type key: string
23    @cvar key: name of security key in session object
24   
25    @type subKeys: tuple
26    @cvar subKeys: list of valid security keys to set"""
27   
28    key = 'ndgSec'
29    subKeys = ('h', 'sid', 'u', 'roles')
30
31    def __init__(self, **subKeys):
32        """Update the security key of session object with the
33        input sub keys
34       
35        type **subKeys: dict
36        param **subKeys: set any of the security keywords as contained in
37        SecuritySession.subKeys"""
38       
39        # Set the security session keys from request.params if no keywords
40        # were input
41        if subKeys == {}:
42            subKeys = LoginServiceQuery.decodeRequestParams()
43           
44        # Ensure security key is present
45        if SecuritySession.key not in session:
46            session[SecuritySession.key] = {}
47         
48        # Ensure valid keys are being set   
49        for k in subKeys:
50            if k not in SecuritySession.subKeys:
51                raise KeyError, 'Invalid key Security session dict: "%s"' % k
52       
53        # Update security values
54        session[SecuritySession.key].update(subKeys)           
55        session.save()
56        log.debug("Set security session: %s" % session[SecuritySession.key])
57
58    @classmethod
59    def delete(self):
60        """Delete security key from session object"""
61        if SecuritySession.key in session:
62            del session[SecuritySession.key]
63            session.save()
64        log.debug("Deleted security key to session object: %s" % session)
65           
66setSecuritySession = SecuritySession
67           
68 
69class LoginServiceQuery(object):
70    """Create query string containing security credentials.  This is used by
71    the Identity Provider pass the credentials over a HTTP GET back to the
72    Service Provider"""
73   
74    keys = SecuritySession.subKeys
75    rolesSep = ","
76    argSep = "&"
77       
78    def __str__(self):
79        """Provide convenient short-cut for call to make query string
80
81        @rtype: string
82        @return: URL query string with security args"""
83        return self.makeQueryStr()
84   
85    @classmethod
86    def makeQueryStr(cls):
87        """Create the query string containing the required security
88        credentials to return to the service provider
89       
90        @rtype: string
91        @return: URL query string with security args"""
92       
93        # Make a copy of the security session dict reseting the
94        # roles to a single string ready for passing over URL
95        secDict = session[SecuritySession.key].copy()
96        secDict['roles'] = cls.rolesSep.join(secDict['roles'])
97       
98        # Return the full query as a string
99        return cls.argSep.join(["%s=%s" % (k, secDict[k]) for k in cls.keys])
100
101    @classmethod
102    def stripFromURI(cls):
103        """Make a new query string using Pylons request.params but stripping
104        args relating to security
105       
106        @rtype: string
107        @return: URL query string with security args removed"""
108        return cls.argSep.join(['%s=%s' % (i, request.params[i]) \
109                                for i in request.params if i not in cls.keys])
110
111    @classmethod
112    def decodeRequestParams(cls):
113        """Get security parameters from request.params received from Login
114        Service (IdP).  Decode parameters where necessary: roles are sent as a
115        comma delimited list - convert into a list type
116       
117        @rtype: dict
118        @return: dictionary of security parameters
119        """
120       
121        try:
122            # request.params is actually a MultiDict type but for the purposes
123            # of this code it can be treated as a regular dict type
124            keys = dict([(k, request.params[k]) for k in cls.keys])
125        except KeyError, e:
126            OwsError, \
127                '%s argument is missing from URL returned by Login Service' %\
128                str(e)
129               
130        # Modify roles from a comma delimited string into a list
131        if 'roles' in keys:
132            keys['roles'] = keys['roles'].split(cls.rolesSep)
133
134        return keys
135   
136import sys
137
138class SecurityConfigError(Exception):
139    """Handle errors from parsing security config items"""
140       
141class SecurityConfig(object):
142    """Get Security related parameters from the Pylons NDG config file"""
143
144    def __init__(self, cfg=None):
145        '''Get PKI settings for Attribute Authority and Session Manager from
146        the configuration file
147       
148        @type param: pylons config file object
149        @param cfg: reference to NDG configuration file.  If omitted defaults
150        to request.environ['ndgConfig']'''
151       
152        if cfg is None:
153            cfg = request.environ['ndgConfig']
154
155        tracefileExpr = cfg.get('NDG_SECURITY', 'tracefile')
156        if tracefileExpr:
157            self.tracefile = eval(tracefileExpr)
158
159        self.smURI = cfg.get('NDG_SECURITY', 'sessionMgrURI')       
160        self.aaURI = cfg.get('NDG_SECURITY', 'attAuthorityURI')
161       
162        # ... for SSL connections to security web services
163        try:
164            self.sslCACertFilePathList = \
165            cfg.get('NDG_SECURITY', 'sslCACertFilePathList').split()
166               
167        except AttributeError:
168            raise SecurityConfigError, \
169                        'No "sslCACertFilePathList" security setting'
170
171        self.sslPeerCertCN = cfg.get('NDG_SECURITY', 'sslPeerCertCN')
172
173        # ...and for WS-Security digital signature
174        self.wssCertFilePath = cfg.get('NDG_SECURITY', 'wssCertFilePath')
175        self.wssPriKeyFilePath = cfg.get('NDG_SECURITY', 'wssKeyFilePath')
176        self.wssPriKeyPwd = cfg.get('NDG_SECURITY', 'wssKeyPwd')
177
178        try:
179            self.wssCACertFilePathList = \
180                cfg.get('NDG_SECURITY', 'wssCACertFilePathList').split()
181               
182        except AttributeError:
183            raise SecurityConfigError, \
184                                'No "wssCACertFilePathList" security setting'
185
186        # Gatekeeper params
187       
188        # Attribute Certificate Issuer
189        self.acIssuer = cfg.get('NDG_SECURITY', 'acIssuer')
190       
191        # verification of X.509 cert back to CA
192        self.acCACertFilePathList = cfg.get('NDG_SECURITY', 
193                                            'acCACertFilePathList')
194
195             
196    def __repr__(self):
197        return '\n'.join(["%s=%s" % (k,v) for k,v in self.__dict__.items() \
198                if k[:2] != "__"])
Note: See TracBrowser for help on using the repository browser.