Skip to content

Commit a4ae1d4

Browse files
authored
Issue 1185 add token to request (#1304)
1 parent 01dd372 commit a4ae1d4

File tree

5 files changed

+88
-1
lines changed

5 files changed

+88
-1
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Jens Timmerman
5656
Jerome Leclanche
5757
Jesse Gibbs
5858
Jim Graham
59+
John Byrne
5960
Jonas Nygaard Pedersen
6061
Jonathan Steffan
6162
Jordi Sanchez

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
## [unreleased]
1818

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

docs/tutorial/tutorial_03.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ will not try to get user from the session.
4747
If you use AuthenticationMiddleware, be sure it appears before OAuth2TokenMiddleware.
4848
However AuthenticationMiddleware is NOT required for using django-oauth-toolkit.
4949

50+
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.
51+
5052
Protect your view
5153
-----------------
5254
The authentication backend will run smoothly with, for example, `login_required` decorators, so

oauth2_provider/middleware.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
import logging
2+
13
from django.contrib.auth import authenticate
24
from django.utils.cache import patch_vary_headers
35

6+
from oauth2_provider.models import AccessToken
7+
8+
9+
log = logging.getLogger(__name__)
10+
411

512
class OAuth2TokenMiddleware:
613
"""
@@ -36,3 +43,20 @@ def __call__(self, request):
3643
response = self.get_response(request)
3744
patch_vary_headers(response, ("Authorization",))
3845
return response
46+
47+
48+
class OAuth2ExtraTokenMiddleware:
49+
def __init__(self, get_response):
50+
self.get_response = get_response
51+
52+
def __call__(self, request):
53+
authheader = request.META.get("HTTP_AUTHORIZATION", "")
54+
if authheader.startswith("Bearer"):
55+
tokenstring = authheader.split()[1]
56+
try:
57+
token = AccessToken.objects.get(token=tokenstring)
58+
request.access_token = token
59+
except AccessToken.DoesNotExist as e:
60+
log.exception(e)
61+
response = self.get_response(request)
62+
return response

tests/test_auth_backends.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from django.utils.timezone import now, timedelta
1111

1212
from oauth2_provider.backends import OAuth2Backend
13-
from oauth2_provider.middleware import OAuth2TokenMiddleware
13+
from oauth2_provider.middleware import OAuth2ExtraTokenMiddleware, OAuth2TokenMiddleware
1414
from oauth2_provider.models import get_access_token_model, get_application_model
1515

1616

@@ -162,3 +162,62 @@ def test_middleware_response_header(self):
162162
response = m(request)
163163
self.assertIn("Vary", response)
164164
self.assertIn("Authorization", response["Vary"])
165+
166+
167+
@override_settings(
168+
AUTHENTICATION_BACKENDS=(
169+
"oauth2_provider.backends.OAuth2Backend",
170+
"django.contrib.auth.backends.ModelBackend",
171+
),
172+
)
173+
@modify_settings(
174+
MIDDLEWARE={
175+
"append": "oauth2_provider.middleware.OAuth2TokenMiddleware",
176+
}
177+
)
178+
class TestOAuth2ExtraTokenMiddleware(BaseTest):
179+
def setUp(self):
180+
super().setUp()
181+
self.anon_user = AnonymousUser()
182+
183+
def dummy_get_response(self, request):
184+
return HttpResponse()
185+
186+
def test_middleware_wrong_headers(self):
187+
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
188+
request = self.factory.get("/a-resource")
189+
m(request)
190+
self.assertFalse(hasattr(request, "access_token"))
191+
auth_headers = {
192+
"HTTP_AUTHORIZATION": "Beerer " + "badstring", # a Beer token for you!
193+
}
194+
request = self.factory.get("/a-resource", **auth_headers)
195+
m(request)
196+
self.assertFalse(hasattr(request, "access_token"))
197+
198+
def test_middleware_token_does_not_exist(self):
199+
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
200+
auth_headers = {
201+
"HTTP_AUTHORIZATION": "Bearer " + "badtokstr",
202+
}
203+
request = self.factory.get("/a-resource", **auth_headers)
204+
m(request)
205+
self.assertFalse(hasattr(request, "access_token"))
206+
207+
def test_middleware_success(self):
208+
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
209+
auth_headers = {
210+
"HTTP_AUTHORIZATION": "Bearer " + "tokstr",
211+
}
212+
request = self.factory.get("/a-resource", **auth_headers)
213+
m(request)
214+
self.assertEqual(request.access_token, self.token)
215+
216+
def test_middleware_response(self):
217+
m = OAuth2ExtraTokenMiddleware(self.dummy_get_response)
218+
auth_headers = {
219+
"HTTP_AUTHORIZATION": "Bearer " + "tokstr",
220+
}
221+
request = self.factory.get("/a-resource", **auth_headers)
222+
response = m(request)
223+
self.assertIsInstance(response, HttpResponse)

0 commit comments

Comments
 (0)