Added 'passthrough_challenge_decider', which avoids re-challenging 401
responses which have been "pre-challenged" by the application.
| | |
| | | After 1.0.13 |
| | | ============ |
| | | |
| | | - Added 'passthrough_challenge_decider', which avoids re-challenging 401 |
| | | responses which have been "pre-challenged" by the application. |
| | | |
| | | - One-hundred percent unit test coverage. |
| | | |
| | | 1.0.13 (2009/4/24) |
| | |
| | | themselves as willing to participate in identification and |
| | | authorization for a request based on this classification. The request |
| | | classification system is pluggable. :mod:`repoze.who` provides a |
| | | default classifier that you may use. You may extend the |
| | | classification system by making :mod:`repoze.who` aware of a different |
| | | request classifier implementation. |
| | | default classifier that you may use. |
| | | |
| | | You may extend the classification system by making :mod:`repoze.who` aware |
| | | of a different request classifier implementation. |
| | | |
| | | Challenge Deciders |
| | | ------------------ |
| | |
| | | response returned from a downstream application requires a challenge |
| | | plugin to fire. When using the default challenge decider, only the |
| | | status is used (if it starts with ``401``, a challenge is required). |
| | | |
| | | :mod:`repoze.who` also provides an alternate challenge decider, |
| | | ``repoze.who.classifiers.passthrough_challenge_decider``, which avoids |
| | | challenging ``401`` responses which have been "pre-challenged" by the |
| | | application. |
| | | |
| | | You may supply a different challenge decider as necessary. |
| | | |
| | | Plugins |
| | |
| | | from paste.httpheaders import USER_AGENT |
| | | from paste.httpheaders import REQUEST_METHOD |
| | | from paste.httpheaders import CONTENT_TYPE |
| | | from paste.httpheaders import USER_AGENT |
| | | from paste.httpheaders import WWW_AUTHENTICATE |
| | | |
| | | import zope.interface |
| | | from repoze.who.interfaces import IRequestClassifier |
| | |
| | | def default_challenge_decider(environ, status, headers): |
| | | return status.startswith('401 ') |
| | | zope.interface.directlyProvides(default_challenge_decider, IChallengeDecider) |
| | | |
| | | def passthrough_challenge_decider(environ, status, headers): |
| | | """ Don't challenge for pre-challenged responses. |
| | | |
| | | o Assume responsese with 'WWW-Authenticate' or an HTML content type |
| | | are pre-challenged. |
| | | """ |
| | | if not status.startswith('401 '): |
| | | return False |
| | | h_dict = dict(headers) |
| | | if 'WWW-Authenticate' in h_dict: |
| | | return False |
| | | ct = h_dict.get('Content-Type') |
| | | if ct is not None: |
| | | return not ct.startswith('text/html') |
| | | return True |
| | | zope.interface.directlyProvides(passthrough_challenge_decider, |
| | | IChallengeDecider) |
| | |
| | | def test_doesnt_challenges_on_non_401(self): |
| | | decider = self._getFUT() |
| | | self.failIf(decider({}, '200 Ok', [])) |
| | | |
| | | class TestPassthroughChallengeDecider(unittest.TestCase): |
| | | |
| | | def _getFUT(self): |
| | | from repoze.who.classifiers import passthrough_challenge_decider |
| | | return passthrough_challenge_decider |
| | | |
| | | def _makeEnviron(self, kw=None): |
| | | environ = {} |
| | | environ['wsgi.version'] = (1,0) |
| | | if kw is not None: |
| | | environ.update(kw) |
| | | return environ |
| | | |
| | | def test_challenges_on_bare_401(self): |
| | | decider = self._getFUT() |
| | | self.failUnless(decider({}, '401 Unauthorized', [])) |
| | | |
| | | def test_doesnt_challenges_on_non_401(self): |
| | | decider = self._getFUT() |
| | | self.failIf(decider({}, '200 Ok', [])) |
| | | |
| | | def test_doesnt_challenges_on_401_with_WWW_Authenticate(self): |
| | | decider = self._getFUT() |
| | | self.failIf(decider({}, '401 Ok', [('WWW-Authenticate', 'xxx')])) |
| | | |
| | | def test_doesnt_challenges_on_401_with_text_html(self): |
| | | decider = self._getFUT() |
| | | self.failIf(decider({}, '401 Ok', [('Content-Type', 'text/html')])) |