1 # -*- coding: utf-8 -*-
3 oauthlib.oauth2.rfc6749
4 ~~~~~~~~~~~~~~~~~~~~~~~
6 This module is an implementation of various logic needed
7 for consuming and providing OAuth 2.0 RFC6749.
9 from __future__ import absolute_import, unicode_literals
13 from oauthlib.common import Request
15 from .base import BaseEndpoint, catch_errors_and_unavailability
17 log = logging.getLogger(__name__)
20 class ResourceEndpoint(BaseEndpoint):
22 """Authorizes access to protected resources.
24 The client accesses protected resources by presenting the access
25 token to the resource server. The resource server MUST validate the
26 access token and ensure that it has not expired and that its scope
27 covers the requested resource. The methods used by the resource
28 server to validate the access token (as well as any error responses)
29 are beyond the scope of this specification but generally involve an
30 interaction or coordination between the resource server and the
31 authorization server::
33 # For most cases, returning a 403 should suffice.
35 The method in which the client utilizes the access token to
36 authenticate with the resource server depends on the type of access
37 token issued by the authorization server. Typically, it involves
38 using the HTTP "Authorization" request header field [RFC2617] with an
39 authentication scheme defined by the specification of the access
40 token type used, such as [RFC6750]::
42 # Access tokens may also be provided in query and body
43 https://example.com/protected?access_token=kjfch2345sdf # Query
44 access_token=sdf23409df # Body
47 def __init__(self, default_token, token_types):
48 BaseEndpoint.__init__(self)
49 self._tokens = token_types
50 self._default_token = default_token
53 def default_token(self):
54 return self._default_token
57 def default_token_type_handler(self):
58 return self.tokens.get(self.default_token)
64 @catch_errors_and_unavailability
65 def verify_request(self, uri, http_method='GET', body=None, headers=None,
67 """Validate client, code etc, return body + headers"""
68 request = Request(uri, http_method, body, headers)
69 request.token_type = self.find_token_type(request)
70 request.scopes = scopes
71 token_type_handler = self.tokens.get(request.token_type,
72 self.default_token_type_handler)
73 log.debug('Dispatching token_type %s request to %r.',
74 request.token_type, token_type_handler)
75 return token_type_handler.validate_request(request), request
77 def find_token_type(self, request):
78 """Token type identification.
80 RFC 6749 does not provide a method for easily differentiating between
81 different token types during protected resource access. We estimate
82 the most likely token type (if any) by asking each known token type
83 to give an estimation based on the request.
85 estimates = sorted(((t.estimate_type(request), n)
86 for n, t in self.tokens.items()))
87 return estimates[0][1] if len(estimates) else None