|
7 | 7 |
|
8 | 8 | import pytest
|
9 | 9 | from starlette.authentication import AuthCredentials
|
| 10 | +from starlette.datastructures import Headers |
10 | 11 | from starlette.exceptions import HTTPException
|
11 | 12 | from starlette.requests import Request
|
12 | 13 | from starlette.types import Message, Receive, Scope, Send
|
@@ -221,6 +222,66 @@ async def test_token_without_expiry(
|
221 | 222 | assert user.access_token == no_expiry_access_token
|
222 | 223 | assert user.scopes == ["read", "write"]
|
223 | 224 |
|
| 225 | + async def test_lowercase_bearer_prefix( |
| 226 | + self, |
| 227 | + mock_oauth_provider: OAuthAuthorizationServerProvider[Any, Any, Any], |
| 228 | + valid_access_token: AccessToken, |
| 229 | + ): |
| 230 | + """Test with lowercase 'bearer' prefix in Authorization header""" |
| 231 | + backend = BearerAuthBackend(provider=mock_oauth_provider) |
| 232 | + add_token_to_provider(mock_oauth_provider, "valid_token", valid_access_token) |
| 233 | + headers = Headers({"Authorization": "bearer valid_token"}) |
| 234 | + scope = {"type": "http", "headers": headers.raw} |
| 235 | + request = Request(scope) |
| 236 | + result = await backend.authenticate(request) |
| 237 | + assert result is not None |
| 238 | + credentials, user = result |
| 239 | + assert isinstance(credentials, AuthCredentials) |
| 240 | + assert isinstance(user, AuthenticatedUser) |
| 241 | + assert credentials.scopes == ["read", "write"] |
| 242 | + assert user.display_name == "test_client" |
| 243 | + assert user.access_token == valid_access_token |
| 244 | + |
| 245 | + async def test_mixed_case_bearer_prefix( |
| 246 | + self, |
| 247 | + mock_oauth_provider: OAuthAuthorizationServerProvider[Any, Any, Any], |
| 248 | + valid_access_token: AccessToken, |
| 249 | + ): |
| 250 | + """Test with mixed 'BeArEr' prefix in Authorization header""" |
| 251 | + backend = BearerAuthBackend(provider=mock_oauth_provider) |
| 252 | + add_token_to_provider(mock_oauth_provider, "valid_token", valid_access_token) |
| 253 | + headers = Headers({"authorization": "BeArEr valid_token"}) |
| 254 | + scope = {"type": "http", "headers": headers.raw} |
| 255 | + request = Request(scope) |
| 256 | + result = await backend.authenticate(request) |
| 257 | + assert result is not None |
| 258 | + credentials, user = result |
| 259 | + assert isinstance(credentials, AuthCredentials) |
| 260 | + assert isinstance(user, AuthenticatedUser) |
| 261 | + assert credentials.scopes == ["read", "write"] |
| 262 | + assert user.display_name == "test_client" |
| 263 | + assert user.access_token == valid_access_token |
| 264 | + |
| 265 | + async def test_mixed_case_authorization_header( |
| 266 | + self, |
| 267 | + mock_oauth_provider: OAuthAuthorizationServerProvider[Any, Any, Any], |
| 268 | + valid_access_token: AccessToken, |
| 269 | + ): |
| 270 | + """Test authentication with mixed 'Authorization' header.""" |
| 271 | + backend = BearerAuthBackend(provider=mock_oauth_provider) |
| 272 | + add_token_to_provider(mock_oauth_provider, "valid_token", valid_access_token) |
| 273 | + headers = Headers({"AuThOrIzAtIoN": "BeArEr valid_token"}) |
| 274 | + scope = {"type": "http", "headers": headers.raw} |
| 275 | + request = Request(scope) |
| 276 | + result = await backend.authenticate(request) |
| 277 | + assert result is not None |
| 278 | + credentials, user = result |
| 279 | + assert isinstance(credentials, AuthCredentials) |
| 280 | + assert isinstance(user, AuthenticatedUser) |
| 281 | + assert credentials.scopes == ["read", "write"] |
| 282 | + assert user.display_name == "test_client" |
| 283 | + assert user.access_token == valid_access_token |
| 284 | + |
224 | 285 |
|
225 | 286 | @pytest.mark.anyio
|
226 | 287 | class TestRequireAuthMiddleware:
|
|
0 commit comments