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

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