Changeset 4907 for TI12-security


Ignore:
Timestamp:
05/02/09 14:53:02 (11 years ago)
Author:
pjkersha
Message:
  • Single Sign On Service logout controller: fixed WSGI Session Manager client instantiation - added Session Manager environ key arg
  • Completed OpenIDRelyingPartyMiddleware - wraps Authkit OpenID RP code adding a custom signin template and logout capability.
Location:
TI12-security/trunk/python
Files:
509 added
5 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/controllers/logout.py

    r4900 r4907  
    4545            smClnt = WSGISessionManagerClient(uri=session['ndgSec']['h'], 
    4646                        environ=request.environ, 
     47                        environKey=self.cfg.smEnvironKey, 
    4748                        tracefile=cfg.tracefile, 
    4849                        sslCACertFilePathList=cfg.sslCACertFilePathList, 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/__init__.py

    r4863 r4907  
    2727        self._app = app 
    2828        self._environ = {} 
     29        self._start_response = None 
    2930        self._pathInfo = None 
    3031        self._path = None 
     
    4647                setattr(self, name, val) 
    4748 
    48     def _initCall(self, environ): 
     49    def _initCall(self, environ, start_response): 
    4950        """Call from derived class' __call__() to set environ and path 
    5051        attributes""" 
    5152        self.environ = environ 
     53        self.start_response = start_response 
    5254        self.setPathInfo() 
    5355        self.setPath() 
     
    5860        ''' 
    5961        def __call__wrapper(self, environ, start_response): 
    60             self._initCall(environ) 
     62            self._initCall(environ, start_response) 
    6163            return __call__(self, environ, start_response) 
    6264 
     
    222224    environ = property(fget=_getEnviron, 
    223225                       fset=_setEnviron, 
    224                        doc="Copy of WSGI environ dict") 
    225      
     226                       doc="Reference to WSGI environ dict") 
     227     
     228    def _setStart_response(self, start_response): 
     229        self._start_response = start_response 
     230         
     231    def _getStart_response(self): 
     232        return self._start_response 
     233     
     234    start_response = property(fget=_getStart_response, 
     235                              fset=_setStart_response, 
     236                              doc="Reference to WSGI start_response function") 
    226237     
    227238class NDGSecurityPathFilter(NDGSecurityMiddlewareBase): 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/provider/__init__.py

    r4900 r4907  
    11151115        """Do a HTTP 302 redirect 
    11161116         
    1117         @type start_response: callable following WSGI start_response convention 
     1117        @type start_response: builtin_function_or_method 
    11181118        @param start_response: WSGI start response callable 
    11191119        @type url: basestring 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/relyingparty/__init__.py

    r4905 r4907  
    3131    '''Implementation of OpenID Relying Party based on AuthKit''' 
    3232    propertyDefaults = { 
    33         'signinInterfaceMiddlewareClass': None 
     33        'signinInterfaceMiddlewareClass': None, 
     34        'baseURL': '', 
     35        'sessionKey': 'beaker.session', 
     36        'reservedPaths': [] 
    3437    } 
    3538    propertyDefaults.update(NDGSecurityMiddlewareBase.propertyDefaults) 
     
    5154 
    5255             
    53         authKitApp = authkit.authenticate.middleware(app, app_conf) 
    54         app = beaker.middleware.SessionMiddleware(authKitApp) 
    55                  
    5656        # Check for sign in template settings 
    5757        if prefix+'signinInterfaceMiddlewareClass' in app_conf: 
    58             if 'authkit.openid.template.obj' in app_conf: 
     58            if 'authkit.openid.template.obj' in app_conf or \ 
     59               'authkit.openid.template.string' in app_conf or \ 
     60               'authkit.openid.template.file' in app_conf: 
    5961                log.warning("OpenID Relying Party " 
    6062                            "'signinInterfaceMiddlewareClass' " 
    61                             "setting overrides 'authkit.openid.template.obj' " 
    62                             "AuthKit setting") 
     63                            "setting overrides 'authkit.openid.template.*' " 
     64                            "AuthKit settings") 
    6365                 
    6466            moduleName, className = \ 
     
    6870            classProperties = {'prefix': signinInterfacePrefix} 
    6971            classProperties.update(app_conf) 
    70             app = instantiateClass(moduleName, className,   
     72            app = instantiateClass(moduleName,  
     73                                   className,   
    7174                                   objectType=SigninInterface,  
    7275                                   classArgs=(app, global_conf), 
     
    7982                        del conf[k] 
    8083         
    81             authKitApp.template = app.getTemplateFunc()#app.makeTemplate() 
    82  
    83         super(OpenIDRelyingPartyMiddleware, self).__init__(app,  
     84            app_conf['authkit.openid.template.string'] = app.makeTemplate() 
     85                 
     86        self.signoutPath = app_conf.get('authkit.cookie.signoutpath') 
     87 
     88        authKitApp = authkit.authenticate.middleware(app, app_conf) 
     89         
     90        super(OpenIDRelyingPartyMiddleware, self).__init__(authKitApp,  
    8491                                                           global_conf,  
    8592                                                           prefix=prefix,  
    8693                                                           **app_conf) 
    87                  
     94 
     95         
     96    @NDGSecurityMiddlewareBase.initCall      
    8897    def __call__(self, environ, start_response): 
    8998        '''Alter start_response to override the status code and force to 401. 
    9099        This will non-browser based client code to bypass the OpenID interface 
     100         
     101        @type environ: dict 
     102        @param environ: WSGI environment variables dictionary 
     103        @type start_response: builtin_function_or_method 
     104        @param start_response: standard WSGI start response function 
    91105        ''' 
    92         def setUnauthorizedResponse(status, header, exc_info=None): 
    93             return start_response("%s %s" % (401, httplib.responses[401]),  
    94                                   header, 
    95                                   exc_info) 
    96              
    97         return self._app(environ, setUnauthorizedResponse) 
    98  
     106        session = environ[self.sessionKey] 
     107        if self.signoutPath is not None and self.pathInfo == self.signoutPath: 
     108            # TODO: Redirect to referrer ... 
     109            referer = session.get( 
     110                        'ndg.security.server.wsgi.openid.relyingparty.referer') 
     111            if referer is not None: 
     112                def setRedirectResponse(status, header, exc_info=None): 
     113                    header.extend([('Location', referer)]) 
     114                    return start_response('302 %s' % httplib.responses[302],  
     115                                          header, 
     116                                          exc_info) 
     117                     
     118                return self._app(environ, setRedirectResponse) 
     119            else: 
     120                log.debug('No referer set for redirect following logout') 
     121                 
     122#        if self.pathInfo not in self.reservedPaths: 
     123        if 'HTTP_REFERER' in environ: 
     124            session['ndg.security.server.wsgi.openid.relyingparty.referer'] = \ 
     125                environ['HTTP_REFERER'] 
     126            session.save() 
     127             
     128        def set401UnauthorizedReponse(status, header, exc_info=None): 
     129            '''Make OpenID Relying Party OpenID prompt page return a 401 
     130            status to signal to non-browser based clients that authentication 
     131            is required.  Requests are filtered on content type so that  
     132            static content such as graphics and style sheets associated with 
     133            the page are let through unaltered 
     134             
     135            @type status: str 
     136            @param status: HTTP status code and status message 
     137            @type header: list 
     138            @param header: list of field, value tuple HTTP header content 
     139            @type exc_info: Exception 
     140            @param exc_info: exception info 
     141            ''' 
     142            _status = status 
     143            for name, val in header: 
     144                if name.lower() == 'content-type' and \ 
     145                   val.startswith('text/html'): 
     146                    _status = "%d %s" % (401, httplib.responses[401]) 
     147                    break 
     148                 
     149            return start_response(_status, header, exc_info) 
     150 
     151        return self._app(environ, set401UnauthorizedReponse) 
     152     
     153    def _redirect(self, url): 
     154        """Do a HTTP 302 redirect 
     155         
     156        @type url: basestring 
     157        @param url: URL to redirect to 
     158        @rtype: list 
     159        @return: empty HTML body 
     160        """ 
     161        self.start_response('302 %s' % httplib.responses[302],  
     162                            [('Content-type', 'text/html'), 
     163                             ('Location', url)]) 
     164        return [] 
     165 
     166    def _setReservedPaths(self, paths): 
     167        if isinstance(paths, basestring): 
     168            self._reservedPaths = [path.strip() for path in paths.split(',')] 
     169        elif isinstance(paths, (tuple, list)): 
     170            self._reservedPaths = paths 
     171        else: 
     172            raise AttributeError("Reserved paths must be a string or list or " 
     173                                 "tuple") 
     174    def _getReservedPaths(self): 
     175        return self._reservedPaths 
     176     
     177    reservedPaths = property(fget=_getReservedPaths, 
     178                             fset=_setReservedPaths, 
     179                             doc="Set paths that logout redirect must avoid " 
     180                                 "e.g. AuthKit OpenID processing") 
     181     
    99182class SigninInterfaceError(Exception): 
    100183    """Base class for SigninInterface exceptions 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/relyingparty/signin_interface/buffet/__init__.py

    r4905 r4907  
    7171         
    7272        staticApp = StaticURLParser(self.staticContentRootDir) 
    73         self._app = Cascade([staticApp, app]) 
     73        self._app = Cascade([staticApp, self._app], catch=(404, 401)) 
    7474         
    7575    def _render(self, templateName, c=None, **kw): 
     
    8787        return self._render('signin', c=self) 
    8888     
    89     @classmethod 
    9089    def getTemplateFunc(self): 
    9190        """Set-up template for OpenID Provider Login""" 
Note: See TracChangeset for help on using the changeset viewer.