source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/config/ssoServiceMiddleware.py @ 5181

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/config/ssoServiceMiddleware.py@5181
Revision 5181, 8.7 KB checked in by pjkersha, 11 years ago (diff)

Added a Policy Information Point to encapsulate subject attribute retrieval.

Line 
1'''
2Security middleware - set-up configuration items
3
4P J Kershaw 18/03/08
5'''
6import authkit.authenticate
7from beaker.middleware import SessionMiddleware
8       
9from os.path import expandvars as xpdvars
10from os.path import dirname
11import logging
12log = logging.getLogger(__name__)
13
14class ndg:
15    '''Class structure to define a namespace for SSO Service config attached
16    Pylons global variable 'g'
17    '''
18    class security:
19        class server:
20            class sso:
21                cfg = None
22                class state:
23                    '''State information specific to server side'''
24                    trustedIdPs = {}
25               
26        class common:
27            '''Client class is also needed for BaseController handler to handle
28            responses from Single Sign On IdP'''
29            class sso:
30                class cfg:
31                    '''Placeholder for server and sslServer attributes'''
32                class state:
33                    '''State information - return to URL should be set each
34                    time a new page is loaded.  In ows_server this is handled
35                    by setting it in ndgPage.kid a template that is extended by
36                    all Browse pages.'''
37                    returnToURL = ''
38                    b64encReturnToURL = ''
39               
40class SSOMiddleware(object):
41           
42    def __init__(self, app, g, app_conf, **kw):
43        log.debug("SSOMiddleware.__init__ ...")
44        ndg.security.server.sso.cfg = SSOServiceConfig(app_conf['configfile'], 
45                                                       **kw)
46       
47        # Copy into client for the benefit of
48        # ndg.security.client.ssoclient.ssoclient.lib.base.BaseController
49        # used to process responses back from SSO IdP
50        ndg.security.common.sso.cfg.server = ndg.security.server.sso.cfg.server
51        ndg.security.common.sso.cfg.sslServer = \
52                                        ndg.security.server.sso.cfg.sslServer
53           
54        g.ndg = ndg
55        self.globals = g
56   
57        # OpenID Middleware
58        app = authkit.authenticate.middleware(app, app_conf)
59        app = SessionMiddleware(app)
60
61        self.app = app
62               
63    def __call__(self, environ, start_response):
64        return self.app(environ, start_response)
65
66
67import sys
68from ConfigParser import SafeConfigParser as ConfigParser
69from ndg.security.common.wssecurity import WSSecurityConfig
70
71class SSOServiceConfigError(Exception):
72    """Handle errors from parsing security config items"""
73       
74class SSOServiceConfig(object):
75    """Get Security related parameters from the Pylons NDG config file"""
76
77    def __init__(self, cfg=None, **parseKw):
78        '''Get PKI settings for Attribute Authority and Session Manager from
79        the configuration file
80       
81        @type cfg: config file object or string
82        @param cfg: reference to NDG configuration file or config file object
83        '''
84       
85        self.wss = {}
86       
87        if isinstance(cfg, basestring):
88            # Assume file path to be read
89            self.read(cfg)
90        else:
91            # Assume existing config type object
92            self.cfg = cfg
93
94        if self.cfg:
95            self.parse(**parseKw)
96
97       
98    def read(self, cfgFilePath):
99        '''Read content of config file into object'''
100        self.cfg = ConfigParser(defaults={'here': dirname(cfgFilePath)})
101        self.cfg.read(cfgFilePath)
102 
103
104    def parse(self, 
105              defSection='DEFAULT', 
106              layoutSection='layout',
107              wssSection='WS-Security'):
108        '''Extract content of config file object into self'''
109             
110        if self.cfg.has_option(defSection, 'tracefile'):       
111            self.tracefile = eval(self.cfg.get(defSection,'tracefile'))   
112        else:
113            self.tracefile = None
114           
115        if self.cfg.has_option(defSection, 'sessionMgrURI'):
116            self.smURI = self.cfg.get(defSection, 'sessionMgrURI')
117        else:
118            self.smURI = None
119           
120        if self.cfg.has_option(defSection, 'sessionManagerEnvironKeyName'):       
121            self.smEnvironKeyName = self.cfg.get(defSection, 
122                                             'sessionManagerEnvironKeyName')
123        else:
124            self.smEnvironKeyName = None
125           
126        if self.cfg.has_option(defSection, 'attributeAuthorityURI'):       
127            self.aaURI = self.cfg.get(defSection, 'attributeAuthorityURI')
128        else:
129            self.aaURI = None
130           
131        if self.cfg.has_option(defSection, 'attributeAuthorityEnvironKeyName'):       
132            self.aaEnvironKeyName = self.cfg.get(defSection, 
133                                             'attributeAuthorityEnvironKeyName')
134        else:
135            self.aaEnvironKeyName = None
136       
137        # ... for SSL connections to security web services
138        try:
139            self.sslCACertFilePathList = \
140            xpdvars(self.cfg.get(defSection, 'sslCACertFilePathList')).split()
141               
142        except AttributeError:
143            raise SSOServiceConfigError, \
144                        'No "sslCACertFilePathList" security setting'
145
146
147        # HTTP Proxy setting for web service connections...
148       
149        # Override an http_proxy env setting 
150        if self.cfg.has_option(defSection, 'httpProxyHost'):
151            self.httpProxyHost = self.cfg.get(defSection, 'httpProxyHost')
152        else:
153            self.httpProxyHost = None
154       
155        # Set this to True if the http_proxy environment variable should be
156        # ignored in this case
157        if self.cfg.has_option(defSection, 'noHttpProxyList'):
158            self.noHttpProxyList = self.cfg.getboolean(defSection, 
159                                                          'noHttpProxyList')
160        else:
161            self.noHttpProxyList = False
162           
163           
164        # If no separate WS-Security config file is set then read these params
165        # from the current config file
166        if self.cfg.has_option(defSection, 'wssCfgFilePath'):
167            path = self.cfg.get(defSection,'wssCfgFilePath', None) 
168            wssCfgFilePath = xpdvars(path)
169        else:
170            wssCfgFilePath = None
171           
172        wss = WSSecurityConfig(cfg=wssCfgFilePath or self.cfg)
173        wss.parse(section=wssSection)
174
175       
176        # Cast to standard dict because WSSecurityConfig object can't be
177        # passed via **kw and dict(wss) doesn't work
178        # TODO: check for cleaner solution - dict(wss)
179        self.wss = dict(wss.items())
180
181
182        # Hostname
183        self.server = self.cfg.get(defSection, 'server', '')
184
185        # For secure connections
186        self.sslServer = self.cfg.get(defSection, 'sslServer', '')
187       
188        # These URLs are referred from template files
189        self.getCredentials = '%s/getCredentials' % self.sslServer       
190        self.logoutURI = '%s/logout' % self.server
191                     
192        # Where Are You From URI         
193        self.wayfuri='%s/wayf' % self.server
194
195        # Flag to enable OpenID interface
196        if self.cfg.has_option(defSection, 'enableOpenID'):
197            self.enableOpenID = self.cfg.getboolean(defSection, 'enableOpenID')
198        else:
199            self.enableOpenID = False
200           
201        # Optional - only required for a standalone SSO deployment
202        if self.cfg.has_section(layoutSection):
203            self.localLink=self.cfg.get(layoutSection, 'localLink', None)
204            self.localImage=self.cfg.get(layoutSection, 'localImage', None)
205            self.localAlt=self.cfg.get(layoutSection, 'localAlt', 
206                                       'Visit Local Site')
207            self.ndgLink=self.cfg.get(layoutSection, 'ndgLink', 
208                                      'http://ndg.nerc.ac.uk')
209            self.ndgImage=self.cfg.get(layoutSection, 'ndgImage', None)
210            self.ndgAlt=self.cfg.get(layoutSection, 'ndgAlt','Visit NDG')
211            self.stfcLink=self.cfg.get(layoutSection, 'stfcLink')
212            self.stfcImage=self.cfg.get(layoutSection, 'stfcImage')
213            self.helpIcon=self.cfg.get(layoutSection, 'helpIcon')
214            self.LeftAlt=self.cfg.get(layoutSection, 'HdrLeftAlt')
215            self.LeftLogo=self.cfg.get(layoutSection, 'HdrLeftLogo')
216            self.pageLogo="bodcHdr"
217            self.icons_xml=self.cfg.get(layoutSection,'Xicon')
218            self.icons_plot=self.cfg.get(layoutSection,'plot')
219            self.icons_prn=self.cfg.get(layoutSection, 'printer')
220       
221        if self.cfg.has_option(defSection, 'disclaimer'):
222            self.disclaimer = self.cfg.get(defSection, 'disclaimer')
223        else:
224            self.disclaimer = ''
225           
226           
227    def __repr__(self):
228        return '\n'.join(["%s=%s" % (k,v) for k,v in self.__dict__.items() \
229                if k[:2] != "__"])
230   
Note: See TracBrowser for help on using the repository browser.