Skip to content

Commit

Permalink
Issue 1185 add token to request (#1304)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhnbyrn committed Aug 30, 2023
1 parent 01dd372 commit a4ae1d4
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Jens Timmerman
Jerome Leclanche
Jesse Gibbs
Jim Graham
John Byrne
Jonas Nygaard Pedersen
Jonathan Steffan
Jordi Sanchez
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [unreleased]

### Added
* #1185 Add middleware for adding access token to request
* #1273 Add caching of loading of OIDC private key.
* #1285 Add post_logout_redirect_uris field in application views.

Expand Down
2 changes: 2 additions & 0 deletions docs/tutorial/tutorial_03.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ will not try to get user from the session.
If you use AuthenticationMiddleware, be sure it appears before OAuth2TokenMiddleware.
However AuthenticationMiddleware is NOT required for using django-oauth-toolkit.

Note, `OAuth2TokenMiddleware` adds the user to the request object. There is also an optional `OAuth2ExtraTokenMiddleware` that adds the `Token` to the request. This makes it convenient to access the `Application` object within your views. To use it just add `oauth2_provider.middleware.OAuth2ExtraTokenMiddleware` to the `MIDDLEWARE` setting.

Protect your view
-----------------
The authentication backend will run smoothly with, for example, `login_required` decorators, so
Expand Down
24 changes: 24 additions & 0 deletions oauth2_provider/middleware.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import logging

from django.contrib.auth import authenticate
from django.utils.cache import patch_vary_headers

from oauth2_provider.models import AccessToken


log = logging.getLogger(__name__)


class OAuth2TokenMiddleware:
"""
Expand Down Expand Up @@ -36,3 +43,20 @@ def __call__(self, request):
response = self.get_response(request)
patch_vary_headers(response, ("Authorization",))
return response


class OAuth2ExtraTokenMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
authheader = request.META.get("HTTP_AUTHORIZATION", "")
if authheader.startswith("Bearer"):
tokenstring = authheader.split()[1]
try:
token = AccessToken.objects.get(token=tokenstring)
request.access_token = token
except AccessToken.DoesNotExist as e:
log.exception(e)
response = self.get_response(request)
return response
61 changes: 60 additions & 1 deletion tests/test_auth_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from django.utils.timezone import now, timedelta

from oauth2_provider.backends import OAuth2Backend
from oauth2_provider.middleware import OAuth2TokenMiddleware
from oauth2_provider.middleware import OAuth2ExtraTokenMiddleware, OAuth2TokenMiddleware
from oauth2_provider.models import get_access_token_model, get_application_model


Expand Down Expand Up @@ -162,3 +162,62 @@ def test_middleware_response_header(self):
response = m(request)
self.assertIn("Vary", response)
self.assertIn("Authorization", response["Vary"])


@override_settings(
AUTHENTICATION_BACKENDS=(
"oauth2_provider.backends.OAuth2Backend",
"django.contrib.auth.backends.ModelBackend",
),
)
@modify_settings(
MIDDLEWARE={
"append": "oauth2_provider.middleware.OAuth2TokenMiddleware",
}
)
class TestOAuth2ExtraTokenMiddleware(BaseTest):
def setUp(self):
super().setUp()
self.anon_user = AnonymousUser()

def dummy_get_response(self, request):
return HttpResponse()

def test_middleware_wrong_headers(self):
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
request = self.factory.get("/a-resource")
m(request)
self.assertFalse(hasattr(request, "access_token"))
auth_headers = {
"HTTP_AUTHORIZATION": "Beerer " + "badstring", # a Beer token for you!
}
request = self.factory.get("/a-resource", **auth_headers)
m(request)
self.assertFalse(hasattr(request, "access_token"))

def test_middleware_token_does_not_exist(self):
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
auth_headers = {
"HTTP_AUTHORIZATION": "Bearer " + "badtokstr",
}
request = self.factory.get("/a-resource", **auth_headers)
m(request)
self.assertFalse(hasattr(request, "access_token"))

def test_middleware_success(self):
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
auth_headers = {
"HTTP_AUTHORIZATION": "Bearer " + "tokstr",
}
request = self.factory.get("/a-resource", **auth_headers)
m(request)
self.assertEqual(request.access_token, self.token)

def test_middleware_response(self):
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
auth_headers = {
"HTTP_AUTHORIZATION": "Bearer " + "tokstr",
}
request = self.factory.get("/a-resource", **auth_headers)
response = m(request)
self.assertIsInstance(response, HttpResponse)

0 comments on commit a4ae1d4

Please sign in to comment.