http-authentication.rst 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. Password-Protected Feeds
  2. ========================
  3. :program:`Universal Feed Parser` supports downloading and parsing
  4. password-protected feeds that are protected by :abbr:`HTTP (Hypertext Transfer Protocol)`
  5. authentication. Both basic and digest authentication are supported.
  6. Downloading a feed protected by basic authentication (the easy way)
  7. -------------------------------------------------------------------
  8. The easiest way is to embed the username and password in the feed
  9. :abbr:`URL (Uniform Resource Locator)` itself.
  10. In this example, the username is test and the password is basic.
  11. ::
  12. >>> import feedparser
  13. >>> d = feedparser.parse('http://test:basic@feedparser.org/docs/examples/basic_auth.xml')
  14. >>> d.feed.title
  15. u'Sample Feed'
  16. The same technique works for digest authentication. (Technically,
  17. :program:`Universal Feed Parser` will attempt basic authentication first, but
  18. if that fails and the server indicates that it requires digest authentication,
  19. :program:`Universal Feed Parser` will automatically re-request the feed with
  20. the appropriate digest authentication headers. *This means that this technique
  21. will send your password to the server in an easily decryptable form.*)
  22. .. _example.auth.inline.digest:
  23. Downloading a feed protected by digest authentication (the easy but horribly insecure way)
  24. ------------------------------------------------------------------------------------------
  25. In this example, the username is test and the password is digest.
  26. ::
  27. >>> import feedparser
  28. >>> d = feedparser.parse('http://test:digest@feedparser.org/docs/examples/digest_auth.xml')
  29. >>> d.feed.title
  30. u'Sample Feed'
  31. You can also construct a HTTPBasicAuthHandler that contains the password
  32. information, then pass that as a handler to the ``parse`` function.
  33. HTTPBasicAuthHandler is part of the standard `urllib2 <http://docs.python.org/lib/module-urllib2.html>`_ module.
  34. Downloading a feed protected by :abbr:`HTTP (Hypertext Transfer Protocol)` basic authentication (the hard way)
  35. --------------------------------------------------------------------------------------------------------------
  36. ::
  37. import urllib2, feedparser
  38. # Construct the authentication handler
  39. auth = urllib2.HTTPBasicAuthHandler()
  40. # Add password information: realm, host, user, password.
  41. # A single handler can contain passwords for multiple sites;
  42. # urllib2 will sort out which passwords get sent to which sites
  43. # based on the realm and host of the URL you're retrieving
  44. auth.add_password('BasicTest', 'feedparser.org', 'test', 'basic')
  45. # Pass the authentication handler to the feed parser.
  46. # handlers is a list because there might be more than one
  47. # type of handler (urllib2 defines lots of different ones,
  48. # and you can build your own)
  49. d = feedparser.parse('http://feedparser.org/docs/examples/basic_auth.xml',
  50. handlers=[auth])
  51. Digest authentication is handled in much the same way, by constructing an
  52. HTTPDigestAuthHandler and populating it with the necessary realm, host, user,
  53. and password information. This is more secure than
  54. :ref:`stuffing the username and password in the URL <example.auth.inline.digest>`,
  55. since the password will be encrypted before being sent to the server.
  56. Downloading a feed protected by :abbr:`HTTP (Hypertext Transfer Protocol)` digest authentication (the secure way)
  57. -----------------------------------------------------------------------------------------------------------------
  58. ::
  59. import urllib2, feedparser
  60. auth = urllib2.HTTPDigestAuthHandler()
  61. auth.add_password('DigestTest', 'feedparser.org', 'test', 'digest')
  62. d = feedparser.parse('http://feedparser.org/docs/examples/digest_auth.xml',
  63. handlers=[auth])
  64. The examples so far have assumed that you know in advance that the feed is
  65. password-protected. But what if you don't know?
  66. If you try to download a password-protected feed without sending all the proper
  67. password information, the server will return an
  68. :abbr:`HTTP (Hypertext Transfer Protocol)` status code ``401``.
  69. :program:`Universal Feed Parser` makes this status code available in
  70. ``d.status``.
  71. Details on the authentication scheme are in ``d.headers['www-authenticate']``.
  72. :program:`Universal Feed Parser` does not do any further parsing on this field;
  73. you will need to parse it yourself. Everything before the first space is the
  74. type of authentication (probably ``Basic`` or ``Digest``), which controls which
  75. type of handler you'll need to construct. The realm name is given as
  76. realm="foo" -- so foo would be your first argument to auth.add_password. Other
  77. information in the www-authenticate header is probably safe to ignore; the
  78. :file:`urllib2` module will handle it for you.
  79. Determining that a feed is password-protected
  80. ---------------------------------------------
  81. ::
  82. >>> import feedparser
  83. >>> d = feedparser.parse('http://feedparser.org/docs/examples/basic_auth.xml')
  84. >>> d.status
  85. 401
  86. >>> d.headers['www-authenticate']
  87. 'Basic realm="Use test/basic"'
  88. >>> d = feedparser.parse('http://feedparser.org/docs/examples/digest_auth.xml')
  89. >>> d.status
  90. 401
  91. >>> d.headers['www-authenticate']
  92. 'Digest realm="DigestTest",
  93. nonce="+LV/uLLdAwA=5d77397291261b9ef256b034e19bcb94f5b7992a",
  94. algorithm=MD5,
  95. qop="auth"'