#25187: Make request available in authentication backends
----------------------------------------+------------------------
               Reporter:  carljm        |          Owner:  nobody
                   Type:  New feature   |         Status:  new
              Component:  contrib.auth  |        Version:  1.8
               Severity:  Normal        |       Keywords:
           Triage Stage:  Unreviewed    |      Has patch:  0
    Needs documentation:  0             |    Needs tests:  0
Patch needs improvement:  0             |  Easy pickings:  0
                  UI/UX:  0             |
----------------------------------------+------------------------
 In some cases it is important for an authentication backend to have access
 to additional data from the request; for instance, the request host (if
 implementing host-based multi-tenancy, where each user should be
 restricted to login only on their assigned host/site).

 Currently, it's quite difficult to do this. The two options are a) making
 the request thread-local, which is temptingly easy but Django otherwise
 has resisted, or b) replacing/copying quite large chunks of code: all of
 `AuthenticationForm.clean()`, `AuthenticationMiddleware`,
 `auth.middleware.get_user` and `auth.get_user`.

 My favorite option to resolve this takes advantage of the fact that
 authentication backends are re-instantiated for every use (by
 `load_backend`), and so the request could be passed into them as an
 instantiation argument, making it always available as `self.request`. This
 avoids needing to change the signatures of any methods on a backend,
 keeping `self.request` unobtrusive for backends which don't need it. It
 does mean that we'd need a deprecation path towards requiring custom
 backends to accept this new initialization parameter; or else we'd need a
 class attribute flag like `accepts_request` to explicitly mark backends
 which want the request.

 The other necessary change would be to pass the request from
 `AuthenticationForm` into `contrib.auth.authenticate`, so it can pass it
 on to the backend instantiation. We've backed ourselves into a bit of a
 corner here with the `**credentials` signature of `authenticate`; we can't
 add even an optional `request` argument without potentially breaking
 existing backends that pass `request` as an actual credential. One option
 would be a new `authenticate_with_request` function which would be used by
 `AuthenticationForm`, but leave the existing `authenticate` signature as-
 is for people who are using it directly.

 Very open to alternative suggestions for how to resolve the basic issue
 here.

--
Ticket URL: <https://code.djangoproject.com/ticket/25187>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/049.1817b6c4321322715fb6df008ef95699%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to