Changeset 5757 for TI12-security


Ignore:
Timestamp:
23/09/09 17:34:01 (10 years ago)
Author:
pjkersha
Message:

Testing SSL Client Authentication middleware with session and redirect middleware to enable wget support for NDG Security.

Location:
TI12-security/trunk/python
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/authn.py

    r5655 r5757  
    1515import logging 
    1616log = logging.getLogger(__name__) 
     17from paste.request import parse_querystring 
    1718from authkit.permissions import UserIn 
    1819 
     
    8283 
    8384         
    84 class AuthNRedirectMiddleware(NDGSecurityMiddlewareBase): 
     85class AuthnRedirectMiddleware(NDGSecurityMiddlewareBase): 
    8586    """Base class for Authentication HTTP redirect initiator and consumer WSGI  
    8687    middleware 
     
    8889    @type propertyDefaults: dict 
    8990    @cvar propertyDefaults: valid configuration property keywords     
    90     @type return2URIArgName: basestring 
    91     @cvar return2URIArgName: name of URI query argument used to pass the  
     91    @type RETURN2URI_ARGNAME: basestring 
     92    @cvar RETURN2URI_ARGNAME: name of URI query argument used to pass the  
    9293    return to URI between initiator and consumer classes""" 
    9394    propertyDefaults = { 
     
    9596    } 
    9697    propertyDefaults.update(NDGSecurityMiddlewareBase.propertyDefaults) 
    97     return2URIArgName = 'ndg.security.r' 
    98  
    99     _isAuthenticated = lambda self: 'REMOTE_USER' in self.environ 
     98    RETURN2URI_ARGNAME = 'ndg.security.r' 
     99    USERNAME_ENVIRON_KEYNAME = 'REMOTE_USER' 
     100     
     101    _isAuthenticated = lambda self: \ 
     102            AuthnRedirectMiddleware.USERNAME_ENVIRON_KEYNAME in self.environ 
     103             
    100104    isAuthenticated = property(fget=_isAuthenticated, 
    101                                doc='boolean for is user logged in') 
    102  
    103 class AuthNRedirectInitiatorMiddleware(AuthNRedirectMiddleware): 
     105                               doc='boolean for, "is user logged in?"') 
     106 
     107class AuthnRedirectInitiatorMiddleware(AuthnRedirectMiddleware): 
    104108    '''Middleware to initiate a redirect to another URI if a user is not  
    105109    authenticated i.e. security cookie is not set 
     
    114118        'redirectURI': None, 
    115119    } 
    116     propertyDefaults.update(AuthNRedirectMiddleware.propertyDefaults) 
     120    propertyDefaults.update(AuthnRedirectMiddleware.propertyDefaults) 
    117121     
    118122 
    119123    triggerStatus = '401' 
    120     id = 'authNRedirectInitiatorMiddleware' 
     124    id = 'AuthnRedirectInitiatorMiddleware' 
    121125 
    122126    def __init__(self, app, global_conf, **app_conf): 
     
    133137        ''' 
    134138        self._redirectURI = None 
    135         super(AuthNRedirectInitiatorMiddleware, self).__init__(app,  
     139        super(AuthnRedirectInitiatorMiddleware, self).__init__(app,  
    136140                                                               global_conf,  
    137141                                                               **app_conf) 
     
    141145        '''Invoke redirect if user is not authenticated''' 
    142146         
    143         log.debug("AuthNRedirectInitiatorMiddleware.__call__ ...") 
     147        log.debug("AuthnRedirectInitiatorMiddleware.__call__ ...") 
    144148         
    145149        if self.isAuthenticated: 
     
    175179        quotedReturn2URI = urllib.quote(return2URI, safe='') 
    176180        return2URIQueryArg = urllib.urlencode( 
    177                     {AuthNRedirectInitiatorMiddleware.return2URIArgName:  
     181                    {AuthnRedirectInitiatorMiddleware.RETURN2URI_ARGNAME:  
    178182                     quotedReturn2URI}) 
    179183 
     
    209213 
    210214 
    211 class AuthNRedirectResponseMiddleware(AuthNRedirectMiddleware): 
    212     """Compliment to AuthNRedirectInitiatorMiddleware  
     215class AuthnRedirectResponseMiddleware(AuthnRedirectMiddleware): 
     216    """Compliment to AuthnRedirectInitiatorMiddleware  
    213217    functioning as the opposite end of the HTTP redirect interface.  It  
    214218    performs the following tasks: 
     
    226230         
    227231        # Check for return to address in URI query args set by  
    228         # AuthNRedirectInitiatorMiddleware in application code stack 
     232        # AuthnRedirectInitiatorMiddleware in application code stack 
    229233        if environ['REQUEST_METHOD'] == "GET": 
    230234            params = dict(parse_querystring(environ)) 
     
    232236            params = {} 
    233237         
    234         quotedReferrer = params.get(self.__class__.return2URIArgName, '') 
     238        quotedReferrer = params.get(self.__class__.RETURN2URI_ARGNAME, '') 
    235239        referrerURI = urllib.unquote(quotedReferrer) 
    236240        if referrerURI: 
    237             session[self.__class__.return2URIArgName] = referrerURI 
     241            session[self.__class__.RETURN2URI_ARGNAME] = referrerURI 
    238242            session.save() 
    239243             
    240244        if self.isAuthenticated: 
    241             return2URI = session.get(self.__class__.return2URIArgName) 
     245            return2URI = session.get(self.__class__.RETURN2URI_ARGNAME) 
    242246            if return2URI is None: 
    243247                log.warning("user is authenticated but no return2URI has been " 
     
    321325        @type start_response: function 
    322326        @param start_response: standard WSGI start response function 
    323  
    324327        """ 
    325328        log.debug("SessionHandlerMiddleware.__call__ ...") 
     
    407410    '''Authentication Middleware Configuration error''' 
    408411 
     412 
    409413class AuthenticationMiddleware(MultiHandler, NDGSecurityMiddlewareBase): 
    410414    '''Handler to intercept 401 Unauthorized HTTP responses and redirect to an 
     
    442446        MultiHandler.__init__(self, app) 
    443447 
    444         self.add_method(AuthNRedirectInitiatorMiddleware.id,  
    445                         AuthNRedirectInitiatorMiddleware.filter_app_factory,  
     448        self.add_method(AuthnRedirectInitiatorMiddleware.id,  
     449                        AuthnRedirectInitiatorMiddleware.filter_app_factory,  
    446450                        global_conf, 
    447451                        prefix=prefix, 
    448452                        **app_conf) 
    449453         
    450         self.add_checker(AuthNRedirectInitiatorMiddleware.id,  
    451                          AuthNRedirectInitiatorMiddleware.checker) 
    452  
     454        self.add_checker(AuthnRedirectInitiatorMiddleware.id,  
     455                         AuthnRedirectInitiatorMiddleware.checker) 
     456 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/openid/relyingparty/__init__.py

    r5555 r5757  
    2424 
    2525from ndg.security.server.wsgi import NDGSecurityMiddlewareBase 
    26 from ndg.security.server.wsgi.authn import AuthNRedirectMiddleware 
     26from ndg.security.server.wsgi.authn import AuthnRedirectMiddleware 
    2727from ndg.security.common.utils.classfactory import instantiateClass 
    2828 
     
    3737    This middleware is to be hosted in it's own security middleware stack. 
    3838    WSGI middleware applications to be protected can be hosted in a separate 
    39     stack.  The AuthNRedirectMiddleware filter can respond to a HTTP  
     39    stack.  The AuthnRedirectMiddleware filter can respond to a HTTP  
    4040    401 response from this stack and redirect to this middleware to initiate 
    41     OpenID based sign in.  AuthNRedirectMiddleware passes a query 
     41    OpenID based sign in.  AuthnRedirectMiddleware passes a query 
    4242    argument in its request containing the URI return address for this  
    4343    middleware to return to following OpenID sign in. 
     
    144144         
    145145        # Check for return to argument in query key value pairs 
    146         self._return2URIKey = AuthNRedirectMiddleware.return2URIArgName + '=' 
     146        self._return2URIKey = AuthnRedirectMiddleware.RETURN2URI_ARGNAME + '=' 
    147147     
    148148        super(OpenIDRelyingPartyMiddleware, self).__init__(app,  
     
    174174         
    175175        # Check for return to address in URI query args set by  
    176         # AuthNRedirectMiddleware in application code stack 
     176        # AuthnRedirectMiddleware in application code stack 
    177177        if environ['REQUEST_METHOD'] == "GET": 
    178178            params = dict(parse_querystring(environ)) 
     
    180180            params = {} 
    181181         
    182         quotedReferrer=params.get(AuthNRedirectMiddleware.return2URIArgName,'') 
     182        quotedReferrer=params.get(AuthnRedirectMiddleware.RETURN2URI_ARGNAME,'') 
    183183        referrer = urllib.unquote(quotedReferrer) 
    184184        referrerPathInfo = urlsplit(referrer)[2] 
     
    248248             
    249249            @type preVerifyOK: int 
    250             @param preVerifyOK: If a verification error is found, this parameter  
    251             will be set to 0 
     250            @param preVerifyOK: If a verification error is found, this  
     251            parameter will be set to 0 
    252252            @type x509StoreCtx: M2Crypto.X509_Store_Context 
    253             @param x509StoreCtx: locate the certificate to be verified and perform  
    254             additional verification steps as needed 
     253            @param x509StoreCtx: locate the certificate to be verified and  
     254            perform additional verification steps as needed 
    255255            @rtype: int 
    256256            @return: controls the strategy of the further verification process.  
    257             - If verify_callback returns 0, the verification process is immediately  
    258             stopped with "verification failed" state. If SSL_VERIFY_PEER is set,  
    259             a verification failure alert is sent to the peer and the TLS/SSL  
    260             handshake is terminated.  
    261             - If verify_callback returns 1, the verification process is continued.  
    262             If verify_callback always returns 1, the TLS/SSL handshake will not be  
    263             terminated with respect to verification failures and the connection  
    264             will be established. The calling process can however retrieve the error 
    265             code of the last verification error using SSL_get_verify_result or  
    266             by maintaining its own error storage managed by verify_callback. 
     257            - If verify_callback returns 0, the verification process is  
     258            immediately stopped with "verification failed" state. If  
     259            SSL_VERIFY_PEER is set, a verification failure alert is sent to the 
     260            peer and the TLS/SSL handshake is terminated.  
     261            - If verify_callback returns 1, the verification process is  
     262            continued.  
     263            If verify_callback always returns 1, the TLS/SSL handshake will not 
     264            be terminated with respect to verification failures and the  
     265            connection  
     266            will be established. The calling process can however retrieve the  
     267            error code of the last verification error using  
     268            SSL_get_verify_result or by maintaining its own error storage  
     269            managed by verify_callback. 
    267270            ''' 
    268271            if preVerifyOK == 0: 
    269                 # Something is wrong with the certificate don't bother proceeding 
    270                 # any further 
     272                # Something is wrong with the certificate don't bother  
     273                # proceeding any further 
    271274                log.error("verifyCallback: pre-verify OK flagged an error " 
    272275                          "with the peer certificate, returning error state " 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/ssl.py

    r5751 r5757  
    8989     
    9090 
    91 class ApacheSSLAuthNMiddleware(NDGSecurityMiddlewareBase): 
     91class ApacheSSLAuthnMiddleware(NDGSecurityMiddlewareBase): 
    9292    """Perform SSL peer certificate authentication making use of Apache 
    9393    SSL environment settings 
     
    104104     
    105105    _isSSLRequest = lambda self: self.environ.get( 
    106                                     ApacheSSLAuthNMiddleware.SSL_KEYNAME) == \ 
    107                                     ApacheSSLAuthNMiddleware.SSL_KEYVALUE 
     106                                    ApacheSSLAuthnMiddleware.SSL_KEYNAME) == \ 
     107                                    ApacheSSLAuthnMiddleware.SSL_KEYVALUE 
    108108    isSSLRequest = property(fget=_isSSLRequest, 
    109109                            doc="Is an SSL request boolean - depends on " 
     
    112112    SSL_CLIENT_CERT_KEYNAME = 'SSL_CLIENT_CERT' 
    113113     
     114    # Options for ini file 
     115    RE_PATH_MATCH_LIST_OPTNAME = 'rePathMatchList' 
     116    CACERT_FILEPATH_LIST_OPTNAME = 'caCertFilePathList' 
     117    CLIENT_CERT_DN_MATCH_LIST_OPTNAME = 'clientCertDNMatchList' 
     118     
    114119    propertyDefaults = { 
    115         'clientCertVerificationClassName': None, 
    116         'rePathMatchList': [], 
    117         'caCertFilePathList': [] 
     120        RE_PATH_MATCH_LIST_OPTNAME: [], 
     121        CACERT_FILEPATH_LIST_OPTNAME: [], 
     122        CLIENT_CERT_DN_MATCH_LIST_OPTNAME: [] 
    118123    } 
    119124    propertyDefaults.update(NDGSecurityMiddlewareBase.propertyDefaults) 
    120125         
    121126    _isSSLClientCertSet = lambda self: bool(self.environ.get( 
    122                             ApacheSSLAuthNMiddleware.SSL_CLIENT_CERT_KEYNAME))  
     127                            ApacheSSLAuthnMiddleware.SSL_CLIENT_CERT_KEYNAME))  
    123128    isSSLClientCertSet = property(fget=_isSSLClientCertSet, 
    124129                                  doc="Check for client X.509 certificate " 
     
    127132    def __init__(self, app, global_conf, prefix='sslAuthn.', **app_conf): 
    128133         
    129         super(ApacheSSLAuthNMiddleware, self).__init__(app,  
     134        super(ApacheSSLAuthnMiddleware, self).__init__(app,  
    130135                                                       global_conf,  
    131136                                                       prefix=prefix, 
     
    134139        self.__caCertFilePathList = None 
    135140        self.__caCertStack = None 
    136         self.__verifyClientCert = None 
    137          
    138         self.rePathMatchList = [re.compile(r) for r in  
    139                                 app_conf.get('rePathMatchList','').split()] 
    140  
    141         self.caCertStack = app_conf.get('caCertFilePathList', []) 
    142          
    143         # A custom class may be specified to determine what verification to 
    144         # apply to the client certificate 
    145         clientCertVerificationClassName = app_conf.get( 
    146                                     prefix+'clientCertVerificationClassName') 
    147         if clientCertVerificationClassName: 
    148             isClientCertVerificationProperty = lambda i: i[0].startswith( 
    149                                             prefix+'clientCertVerification.') 
    150             clientCertVerificationProperties = \ 
    151                 dict(filter(isClientCertVerificationProperty,app_conf.items())) 
     141        self.__clientCertDNMatchList = None 
     142        self.__clientCert = None 
     143         
     144        rePathMatchListVal = app_conf.get( 
     145                ApacheSSLAuthnMiddleware.RE_PATH_MATCH_LIST_OPTNAME, '') 
     146        self.rePathMatchList = [re.compile(r)  
     147                                for r in rePathMatchListVal.split()] 
     148 
     149        self.caCertStack = app_conf.get( 
     150                ApacheSSLAuthnMiddleware.CACERT_FILEPATH_LIST_OPTNAME, []) 
     151         
     152        self.clientCertDNMatchList = app_conf.get( 
     153                ApacheSSLAuthnMiddleware.CLIENT_CERT_DN_MATCH_LIST_OPTNAME, []) 
    152154                 
    153             self.verifyClientCert = instantiateClass( 
    154                              clientCertVerificationClassName,  
    155                              None,  
    156                              objectType=ClientCertVerificationInterface,  
    157                              classProperties=clientCertVerificationProperties)             
    158         else:  
    159             # Default to carry out no verification 
    160             self.verifyClientCert = NoClientCertVerification() 
    161          
    162155    def _setCACertStack(self, caCertList): 
    163156        '''Read CA certificates from file and add them to an X.509 Cert. 
     
    215208                           doc="CA certificate stack object - " 
    216209                               "peer certificate must validate against one") 
    217      
    218     def _setVerifyClientCert(self, value): 
    219         ''' 
    220         @type value: ClientCertVerificationInterface derived type 
    221         @param value: custom SSL client verification interface 
    222         ''' 
    223          
    224         if not isinstance(value, ClientCertVerificationInterface): 
    225             raise TypeError('Expecting %r type for "verifyClientCert"; got ' 
    226                             '%r' % type(value)) 
    227          
    228         if not callable(value): 
    229             raise TypeError('Expecting callable for "verifyClientCert"') 
    230          
    231         self.__verifyClientCert = value 
    232      
    233     def _getVerifyClientCert(self): 
    234         return self.__verifyClientCert 
    235  
    236     verifyClientCert = property(fset=_setVerifyClientCert, 
    237                                 fget=_getVerifyClientCert, 
    238                                 doc="Client certificate verification " 
    239                                     "interface object") 
     210         
     211    def _setClientCertDNMatchList(self, value): 
     212        '''         
     213        @type value: basestring, list, tuple 
     214        @param value: list of client certificate Distinguished Names as strings 
     215        of X500DN instances''' 
     216         
     217        if isinstance(value, basestring): 
     218            # Try parsing a space separated list of file paths 
     219            self.__clientCertDNMatchList = [X500DN(dn=dn)  
     220                                            for dn in value.split()] 
     221             
     222        elif isinstance(value, (list, tuple)): 
     223            self.__clientCertDNMatchList = [] 
     224            for dn in value: 
     225                if isinstance(dn, basestring): 
     226                    self.__clientCertDNMatchList.append(X500DN(dn=dn)) 
     227                elif isinstance(dn, X500DN): 
     228                    self.__clientCertDNMatchList.append(dn) 
     229                else: 
     230                    raise TypeError('Expecting a string, or %r type for "%s" ' 
     231                                    'list item; got %r' %  
     232                (X500DN, 
     233                 ApacheSSLAuthnMiddleware.CLIENT_CERT_DN_MATCH_LIST_OPTNAME, 
     234                 type(dn))) 
     235                     
     236        else: 
     237            raise TypeError('Expecting a string, list or tuple for "%s"; got ' 
     238                            '%r' %  
     239                (ApacheSSLAuthnMiddleware.CLIENT_CERT_DN_MATCH_LIST_OPTNAME, 
     240                 type(value))) 
     241     
     242    def _getClientCertDNMatchList(self): 
     243        return self.__clientCertDNMatchList 
     244 
     245    clientCertDNMatchList = property(fset=_setClientCertDNMatchList, 
     246                                     fget=_getClientCertDNMatchList, 
     247                                     doc="List of acceptable Distinguished " 
     248                                         "Names for client certificates") 
     249         
     250    def _getClientCert(self): 
     251        return self.__clientCert 
     252 
     253    clientCert = property(fget=_getClientCert, 
     254                          doc="Client certificate for verification set by " 
     255                              "isValidClientCert()") 
    240256     
    241257    @NDGSecurityMiddlewareBase.initCall          
    242258    def __call__(self, environ, start_response): 
    243259        '''Check for peer certificate in environment and if present carry out 
    244         authentication''' 
    245         log.debug("ApacheSSLAuthNMiddleware.__call__ ...") 
     260        authentication 
     261         
     262        @type environ: dict 
     263        @param environ: WSGI environment variables dictionary 
     264        @type start_response: function 
     265        @param start_response: standard WSGI start response function 
     266        ''' 
     267        log.debug("ApacheSSLAuthnMiddleware.__call__ ...") 
    246268         
    247269        if not self._pathMatch(): 
    248             log.debug("ApacheSSLAuthNMiddleware: ignoring path [%s]",  
     270            log.debug("ApacheSSLAuthnMiddleware: ignoring path [%s]",  
    249271                      self.pathInfo) 
    250272            return self._setResponse() 
    251273         
    252274        elif not self.isSSLRequest: 
    253             log.warning("ApacheSSLAuthNMiddleware: 'HTTPS' environment " 
     275            log.warning("ApacheSSLAuthnMiddleware: 'HTTPS' environment " 
    254276                        "variable not found in environment; ignoring request") 
    255277            return self._setResponse() 
    256278                         
    257279        elif not self.isSSLClientCertSet: 
    258             log.error("ApacheSSLAuthNMiddleware: No SSL Client certificate " 
     280            log.error("ApacheSSLAuthnMiddleware: No SSL Client certificate " 
    259281                      "for request to [%s]; setting HTTP 401 Unauthorized",  
    260282                      self.pathInfo) 
     
    267289            return self._setErrorResponse(code=401) 
    268290 
    269              
    270291    def _setResponse(self,  
    271292                     notFoundMsg='No application set for ' 
    272                                  'ApacheSSLAuthNMiddleware', 
     293                                 'ApacheSSLAuthnMiddleware', 
    273294                     **kw): 
    274         return super(ApacheSSLAuthNMiddleware,  
     295        return super(ApacheSSLAuthnMiddleware,  
    275296                     self)._setResponse(notFoundMsg=notFoundMsg, **kw) 
    276297 
    277298    def _setErrorResponse(self, msg='Invalid SSL client certificate', **kw): 
    278         return super(ApacheSSLAuthNMiddleware, self)._setErrorResponse(msg=msg, 
     299        return super(ApacheSSLAuthnMiddleware, self)._setErrorResponse(msg=msg, 
    279300                                                                       **kw) 
    280301 
     
    293314    def isValidClientCert(self): 
    294315        sslClientCert = self.environ[ 
    295                             ApacheSSLAuthNMiddleware.SSL_CLIENT_CERT_KEYNAME] 
    296         x509Cert = X509Cert.Parse(sslClientCert) 
     316                            ApacheSSLAuthnMiddleware.SSL_CLIENT_CERT_KEYNAME] 
     317        self.__clientCert = X509Cert.Parse(sslClientCert) 
    297318         
    298319        if len(self.caCertStack) == 0: 
     
    301322        else: 
    302323            try: 
    303                 self.caCertStack.verifyCertChain(x509Cert2Verify=x509Cert) 
     324                self.caCertStack.verifyCertChain( 
     325                                            x509Cert2Verify=self.__clientCert) 
    304326 
    305327            except X509CertError, e: 
    306328                log.info("Client certificate verification failed with %s " 
    307                          "exception: %s" % (e.__class__, e)) 
     329                         "exception: %s" % (type(e), e)) 
    308330                return False 
    309331             
    310332            except Exception, e: 
    311333                log.error("Client certificate verification failed with " 
    312                           "unexpected exception type %s: %s" % (e.__class__,e)) 
     334                          "unexpected exception type %s: %s" % (type(e), e)) 
    313335                return False 
    314          
    315         # Check certificate Distinguished Name via  
    316         # ClientCertVerificationInterface object 
    317         return self.verifyClientCert(x509Cert) 
    318  
     336             
     337        if len(self.clientCertDNMatchList) > 0: 
     338            if self.__clientCert.dn not in self.clientCertDNMatchList: 
     339                return False 
     340             
     341        return True 
     342#         
     343#        # Check certificate Distinguished Name via  
     344#        # ClientCertVerificationInterface object 
     345#        return self.verifyClientCert(x509Cert) 
     346     
     347 
     348class AuthKitSSLAuthnMiddleware(ApacheSSLAuthnMiddleware): 
     349    """Update REMOTE_USER AuthKit environ key with certificate CommonName to 
     350    flag logged in status to other middleware 
     351    """ 
     352    @NDGSecurityMiddlewareBase.initCall          
     353    def __call__(self, environ, start_response): 
     354        '''Check for peer certificate in environment and if present carry out 
     355        authentication.  Overrides parent class behaviour to set REMOTE_USER 
     356        AuthKit environ key based on the client certificate's Distinguished  
     357        Name CommonName field.  If no certificate is present or it is  
     358        present but invalid no 401 response is set.  Instead, it is left to 
     359        the following middleware in the chain to deal with this.  When used 
     360        in conjunction with  
     361        ndg.security.server.wsgi.openid.relyingparty.OpenIDRelyingPartyMiddleware, 
     362        this will result in the display of the Relying Party interface but with 
     363        a 401 status set. 
     364         
     365        @type environ: dict 
     366        @param environ: WSGI environment variables dictionary 
     367        @type start_response: function 
     368        @param start_response: standard WSGI start response function 
     369        ''' 
     370        if not self._pathMatch(): 
     371            log.debug("AuthKitSSLAuthnMiddleware: ignoring path [%s]",  
     372                      self.pathInfo) 
     373 
     374        elif not self.isSSLRequest: 
     375            log.warning("AuthKitSSLAuthnMiddleware: 'HTTPS' environment " 
     376                        "variable not found in environment; ignoring request") 
     377                         
     378        elif not self.isSSLClientCertSet: 
     379            log.debug("AuthKitSSLAuthnMiddleware: no client certificate set - " 
     380                      "passing request to next middleware in the chain ...") 
     381             
     382        elif self.isValidClientCert(): 
     383            # Update environ so that downstream AuthenticationMiddleware can 
     384            # set the session cookie 
     385            self.environ['REMOTE_USER'] = self.clientCert.dn['CN'] 
     386             
     387            # Set-up redirect back to original request URI 
     388        else: 
     389            # IsValidCert will log warnings/errors no need to flag this 
     390            # condition 
     391            pass 
     392             
     393        # Pass request to next middleware in the chain without setting an 
     394        # error response - see method doc string for explanation. 
     395        return self._setResponse() 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/authn/test.ini

    r5637 r5757  
    1515 
    1616[app:TestApp] 
    17 paste.app_factory = ndg.security.test.unit.wsgi.authn.test_authn:TestAuthNApp 
     17paste.app_factory = ndg.security.test.unit.wsgi.authn.test_authn:TestAuthnApp 
    1818 
    1919[filter:AuthNRedirectFilter] 
    20 paste.filter_app_factory = ndg.security.server.wsgi.authn:AuthNRedirectInitiatorMiddleware 
     20paste.filter_app_factory = ndg.security.server.wsgi.authn:AuthnRedirectInitiatorMiddleware 
    2121prefix = authN. 
    2222authN.redirectURI = /redirect2here 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/authn/test_authn.py

    r5637 r5757  
    2828import paste.fixture 
    2929from paste.deploy import loadapp 
     30from ndg.security.test.unit import BaseTestCase 
     31from ndg.security.common.X509 import X509Cert 
     32from ndg.security.server.wsgi.ssl import AuthKitSSLAuthnMiddleware 
    3033 
    31 class TestAuthNApp(object): 
     34 
     35class TestAuthnApp(object): 
    3236    '''Test Application for the Authentication handler to protect''' 
    3337    response = "Test Authentication redirect application" 
     
    5559        start_response(status, 
    5660                       [('Content-length',  
    57                          str(len(TestAuthNApp.response))), 
     61                         str(len(TestAuthnApp.response))), 
    5862                        ('Content-type', 'text/plain')]) 
    59         return [TestAuthNApp.response] 
     63        return [TestAuthnApp.response] 
    6064 
    6165 
     
    6973        unittest.TestCase.__init__(self, *args, **kwargs) 
    7074         
    71  
    7275    def test01Catch401WithNotLoggedIn(self): 
    7376        response = self.app.get('/test_401WithNotLoggedIn') 
     
    98101            self.failIf('404 Not found' not in str(e),  
    99102                        "Expecting 404 Not found") 
     103 
     104 
     105class WsgiSSLClientAuthnTestController(BaseTestCase): 
     106    """Extend Authentication middleware test to use SSL Client Authentication 
     107    middleware""" 
    100108     
     109    def __init__(self, *arg, **kw): 
     110        here_dir = os.path.dirname(os.path.abspath(__file__)) 
     111        wsgiapp = loadapp('config:ssl-test.ini', relative_to=here_dir) 
     112        self.app = paste.fixture.TestApp(wsgiapp) 
     113          
     114        BaseTestCase.__init__(self, *arg, **kw) 
     115         
     116    def test01Catch401WithNotLoggedIn(self): 
     117        thisDir = os.path.dirname(__file__) 
     118        sslClientCertFilePath = os.path.join( 
     119                                os.environ[BaseTestCase.configDirEnvVarName], 
     120                                'pki', 
     121                                'test.crt') 
     122        sslClientCert = X509Cert.Read(sslClientCertFilePath).toString() 
     123        extra_environ = {'HTTPS':'1', 'SSL_CLIENT_CERT': sslClientCert} 
    101124 
     125        response = self.app.get('/test_401WithNotLoggedIn', 
     126                                extra_environ=extra_environ, 
     127                                status=302) 
     128         
     129        redirectResponse = response.follow(extra_environ=extra_environ, 
     130                                           status=302) 
     131         
     132        finalResponse = redirectResponse.follow(extra_environ=extra_environ) 
     133         
     134        print finalResponse 
     135         
     136     
    102137if __name__ == "__main__": 
    103138    unittest.main()         
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/ssl/test.ini

    r5343 r5757  
    11# 
    2 # SSL Client AuthN WSGI Testing environment configuration 
     2# SSL Client Authn WSGI Testing environment configuration 
    33# 
    44# The %(here)s variable will be replaced with the parent directory of this file 
     
    66[DEFAULT] 
    77testConfigDir = ../../../config 
     8 
    89[server:main] 
    910use = egg:Paste#http 
     
    1213 
    1314[pipeline:main] 
    14 pipeline = SSLClientAuthNFilter TestApp 
     15pipeline = SSLClientAuthnFilter TestApp 
    1516 
    1617[app:TestApp] 
    17 paste.app_factory = ndg.security.test.unit.wsgi.ssl.test_ssl:TestSSLClientAuthNMiddleware 
     18paste.app_factory = ndg.security.test.unit.wsgi.ssl.test_ssl:TestSSLClientAuthnApp 
    1819 
    19 [filter:SSLClientAuthNFilter] 
    20 paste.filter_app_factory = ndg.security.server.wsgi.ssl:ApacheSSLAuthNMiddleware 
     20[filter:SSLClientAuthnFilter] 
     21paste.filter_app_factory = ndg.security.server.wsgi.ssl:ApacheSSLAuthnMiddleware 
    2122prefix = ssl. 
    2223caCertFilePathList = %(testConfigDir)s/ca/ndg-test-ca.crt 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/ssl/test_ssl.py

    r5362 r5757  
    2121from ndg.security.common.X509 import X509Cert 
    2222 
    23 class TestSSLClientAuthNMiddleware(BaseTestCase): 
     23class TestSSLClientAuthnApp(BaseTestCase): 
    2424    '''Test Application for the Authentication handler to protect''' 
    2525    response = "Test Authentication redirect application" 
     
    4747        start_response(status, 
    4848                       [('Content-length',  
    49                          str(len(TestSSLClientAuthNMiddleware.response))), 
     49                         str(len(TestSSLClientAuthnApp.response))), 
    5050                        ('Content-type', 'text/plain')]) 
    51         return [TestSSLClientAuthNMiddleware.response] 
     51        return [TestSSLClientAuthnApp.response] 
    5252 
    5353 
     
    8585                                status=200) 
    8686 
    87      
    8887 
    8988if __name__ == "__main__": 
Note: See TracChangeset for help on using the changeset viewer.