request_validator.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. """
  2. oauthlib.oauth2.rfc6749.request_validator
  3. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. """
  5. import logging
  6. log = logging.getLogger(__name__)
  7. class RequestValidator:
  8. def client_authentication_required(self, request, *args, **kwargs):
  9. """Determine if client authentication is required for current request.
  10. According to the rfc6749, client authentication is required in the following cases:
  11. - Resource Owner Password Credentials Grant, when Client type is Confidential or when
  12. Client was issued client credentials or whenever Client provided client
  13. authentication, see `Section 4.3.2`_.
  14. - Authorization Code Grant, when Client type is Confidential or when Client was issued
  15. client credentials or whenever Client provided client authentication,
  16. see `Section 4.1.3`_.
  17. - Refresh Token Grant, when Client type is Confidential or when Client was issued
  18. client credentials or whenever Client provided client authentication, see
  19. `Section 6`_
  20. :param request: OAuthlib request.
  21. :type request: oauthlib.common.Request
  22. :rtype: True or False
  23. Method is used by:
  24. - Authorization Code Grant
  25. - Resource Owner Password Credentials Grant
  26. - Refresh Token Grant
  27. .. _`Section 4.3.2`: https://tools.ietf.org/html/rfc6749#section-4.3.2
  28. .. _`Section 4.1.3`: https://tools.ietf.org/html/rfc6749#section-4.1.3
  29. .. _`Section 6`: https://tools.ietf.org/html/rfc6749#section-6
  30. """
  31. return True
  32. def authenticate_client(self, request, *args, **kwargs):
  33. """Authenticate client through means outside the OAuth 2 spec.
  34. Means of authentication is negotiated beforehand and may for example
  35. be `HTTP Basic Authentication Scheme`_ which utilizes the Authorization
  36. header.
  37. Headers may be accesses through request.headers and parameters found in
  38. both body and query can be obtained by direct attribute access, i.e.
  39. request.client_id for client_id in the URL query.
  40. The authentication process is required to contain the identification of
  41. the client (i.e. search the database based on the client_id). In case the
  42. client doesn't exist based on the received client_id, this method has to
  43. return False and the HTTP response created by the library will contain
  44. 'invalid_client' message.
  45. After the client identification succeeds, this method needs to set the
  46. client on the request, i.e. request.client = client. A client object's
  47. class must contain the 'client_id' attribute and the 'client_id' must have
  48. a value.
  49. :param request: OAuthlib request.
  50. :type request: oauthlib.common.Request
  51. :rtype: True or False
  52. Method is used by:
  53. - Authorization Code Grant
  54. - Resource Owner Password Credentials Grant (may be disabled)
  55. - Client Credentials Grant
  56. - Refresh Token Grant
  57. .. _`HTTP Basic Authentication Scheme`: https://tools.ietf.org/html/rfc1945#section-11.1
  58. """
  59. raise NotImplementedError('Subclasses must implement this method.')
  60. def authenticate_client_id(self, client_id, request, *args, **kwargs):
  61. """Ensure client_id belong to a non-confidential client.
  62. A non-confidential client is one that is not required to authenticate
  63. through other means, such as using HTTP Basic.
  64. Note, while not strictly necessary it can often be very convenient
  65. to set request.client to the client object associated with the
  66. given client_id.
  67. :param client_id: Unicode client identifier.
  68. :param request: OAuthlib request.
  69. :type request: oauthlib.common.Request
  70. :rtype: True or False
  71. Method is used by:
  72. - Authorization Code Grant
  73. """
  74. raise NotImplementedError('Subclasses must implement this method.')
  75. def confirm_redirect_uri(self, client_id, code, redirect_uri, client, request,
  76. *args, **kwargs):
  77. """Ensure that the authorization process represented by this authorization
  78. code began with this 'redirect_uri'.
  79. If the client specifies a redirect_uri when obtaining code then that
  80. redirect URI must be bound to the code and verified equal in this
  81. method, according to RFC 6749 section 4.1.3. Do not compare against
  82. the client's allowed redirect URIs, but against the URI used when the
  83. code was saved.
  84. :param client_id: Unicode client identifier.
  85. :param code: Unicode authorization_code.
  86. :param redirect_uri: Unicode absolute URI.
  87. :param client: Client object set by you, see ``.authenticate_client``.
  88. :param request: OAuthlib request.
  89. :type request: oauthlib.common.Request
  90. :rtype: True or False
  91. Method is used by:
  92. - Authorization Code Grant (during token request)
  93. """
  94. raise NotImplementedError('Subclasses must implement this method.')
  95. def get_default_redirect_uri(self, client_id, request, *args, **kwargs):
  96. """Get the default redirect URI for the client.
  97. :param client_id: Unicode client identifier.
  98. :param request: OAuthlib request.
  99. :type request: oauthlib.common.Request
  100. :rtype: The default redirect URI for the client
  101. Method is used by:
  102. - Authorization Code Grant
  103. - Implicit Grant
  104. """
  105. raise NotImplementedError('Subclasses must implement this method.')
  106. def get_default_scopes(self, client_id, request, *args, **kwargs):
  107. """Get the default scopes for the client.
  108. :param client_id: Unicode client identifier.
  109. :param request: OAuthlib request.
  110. :type request: oauthlib.common.Request
  111. :rtype: List of default scopes
  112. Method is used by all core grant types:
  113. - Authorization Code Grant
  114. - Implicit Grant
  115. - Resource Owner Password Credentials Grant
  116. - Client Credentials grant
  117. """
  118. raise NotImplementedError('Subclasses must implement this method.')
  119. def get_original_scopes(self, refresh_token, request, *args, **kwargs):
  120. """Get the list of scopes associated with the refresh token.
  121. :param refresh_token: Unicode refresh token.
  122. :param request: OAuthlib request.
  123. :type request: oauthlib.common.Request
  124. :rtype: List of scopes.
  125. Method is used by:
  126. - Refresh token grant
  127. """
  128. raise NotImplementedError('Subclasses must implement this method.')
  129. def is_within_original_scope(self, request_scopes, refresh_token, request, *args, **kwargs):
  130. """Check if requested scopes are within a scope of the refresh token.
  131. When access tokens are refreshed the scope of the new token
  132. needs to be within the scope of the original token. This is
  133. ensured by checking that all requested scopes strings are on
  134. the list returned by the get_original_scopes. If this check
  135. fails, is_within_original_scope is called. The method can be
  136. used in situations where returning all valid scopes from the
  137. get_original_scopes is not practical.
  138. :param request_scopes: A list of scopes that were requested by client.
  139. :param refresh_token: Unicode refresh_token.
  140. :param request: OAuthlib request.
  141. :type request: oauthlib.common.Request
  142. :rtype: True or False
  143. Method is used by:
  144. - Refresh token grant
  145. """
  146. return False
  147. def introspect_token(self, token, token_type_hint, request, *args, **kwargs):
  148. """Introspect an access or refresh token.
  149. Called once the introspect request is validated. This method should
  150. verify the *token* and either return a dictionary with the list of
  151. claims associated, or `None` in case the token is unknown.
  152. Below the list of registered claims you should be interested in:
  153. - scope : space-separated list of scopes
  154. - client_id : client identifier
  155. - username : human-readable identifier for the resource owner
  156. - token_type : type of the token
  157. - exp : integer timestamp indicating when this token will expire
  158. - iat : integer timestamp indicating when this token was issued
  159. - nbf : integer timestamp indicating when it can be "not-before" used
  160. - sub : subject of the token - identifier of the resource owner
  161. - aud : list of string identifiers representing the intended audience
  162. - iss : string representing issuer of this token
  163. - jti : string identifier for the token
  164. Note that most of them are coming directly from JWT RFC. More details
  165. can be found in `Introspect Claims`_ or `JWT Claims`_.
  166. The implementation can use *token_type_hint* to improve lookup
  167. efficiency, but must fallback to other types to be compliant with RFC.
  168. The dict of claims is added to request.token after this method.
  169. :param token: The token string.
  170. :param token_type_hint: access_token or refresh_token.
  171. :param request: OAuthlib request.
  172. :type request: oauthlib.common.Request
  173. Method is used by:
  174. - Introspect Endpoint (all grants are compatible)
  175. .. _`Introspect Claims`: https://tools.ietf.org/html/rfc7662#section-2.2
  176. .. _`JWT Claims`: https://tools.ietf.org/html/rfc7519#section-4
  177. """
  178. raise NotImplementedError('Subclasses must implement this method.')
  179. def invalidate_authorization_code(self, client_id, code, request, *args, **kwargs):
  180. """Invalidate an authorization code after use.
  181. :param client_id: Unicode client identifier.
  182. :param code: The authorization code grant (request.code).
  183. :param request: OAuthlib request.
  184. :type request: oauthlib.common.Request
  185. Method is used by:
  186. - Authorization Code Grant
  187. """
  188. raise NotImplementedError('Subclasses must implement this method.')
  189. def revoke_token(self, token, token_type_hint, request, *args, **kwargs):
  190. """Revoke an access or refresh token.
  191. :param token: The token string.
  192. :param token_type_hint: access_token or refresh_token.
  193. :param request: OAuthlib request.
  194. :type request: oauthlib.common.Request
  195. Method is used by:
  196. - Revocation Endpoint
  197. """
  198. raise NotImplementedError('Subclasses must implement this method.')
  199. def rotate_refresh_token(self, request):
  200. """Determine whether to rotate the refresh token. Default, yes.
  201. When access tokens are refreshed the old refresh token can be kept
  202. or replaced with a new one (rotated). Return True to rotate and
  203. and False for keeping original.
  204. :param request: OAuthlib request.
  205. :type request: oauthlib.common.Request
  206. :rtype: True or False
  207. Method is used by:
  208. - Refresh Token Grant
  209. """
  210. return True
  211. def save_authorization_code(self, client_id, code, request, *args, **kwargs):
  212. """Persist the authorization_code.
  213. The code should at minimum be stored with:
  214. - the client_id (``client_id``)
  215. - the redirect URI used (``request.redirect_uri``)
  216. - a resource owner / user (``request.user``)
  217. - the authorized scopes (``request.scopes``)
  218. To support PKCE, you MUST associate the code with:
  219. - Code Challenge (``request.code_challenge``) and
  220. - Code Challenge Method (``request.code_challenge_method``)
  221. To support OIDC, you MUST associate the code with:
  222. - nonce, if present (``code["nonce"]``)
  223. The ``code`` argument is actually a dictionary, containing at least a
  224. ``code`` key with the actual authorization code:
  225. ``{'code': 'sdf345jsdf0934f'}``
  226. It may also have a ``claims`` parameter which, when present, will be a dict
  227. deserialized from JSON as described at
  228. http://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter
  229. This value should be saved in this method and used again in ``.validate_code``.
  230. :param client_id: Unicode client identifier.
  231. :param code: A dict of the authorization code grant and, optionally, state.
  232. :param request: OAuthlib request.
  233. :type request: oauthlib.common.Request
  234. Method is used by:
  235. - Authorization Code Grant
  236. """
  237. raise NotImplementedError('Subclasses must implement this method.')
  238. def save_token(self, token, request, *args, **kwargs):
  239. """Persist the token with a token type specific method.
  240. Currently, only save_bearer_token is supported.
  241. :param token: A (Bearer) token dict.
  242. :param request: OAuthlib request.
  243. :type request: oauthlib.common.Request
  244. """
  245. return self.save_bearer_token(token, request, *args, **kwargs)
  246. def save_bearer_token(self, token, request, *args, **kwargs):
  247. """Persist the Bearer token.
  248. The Bearer token should at minimum be associated with:
  249. - a client and it's client_id, if available
  250. - a resource owner / user (request.user)
  251. - authorized scopes (request.scopes)
  252. - an expiration time
  253. - a refresh token, if issued
  254. - a claims document, if present in request.claims
  255. The Bearer token dict may hold a number of items::
  256. {
  257. 'token_type': 'Bearer',
  258. 'access_token': 'askfjh234as9sd8',
  259. 'expires_in': 3600,
  260. 'scope': 'string of space separated authorized scopes',
  261. 'refresh_token': '23sdf876234', # if issued
  262. 'state': 'given_by_client', # if supplied by client (implicit ONLY)
  263. }
  264. Note that while "scope" is a string-separated list of authorized scopes,
  265. the original list is still available in request.scopes.
  266. The token dict is passed as a reference so any changes made to the dictionary
  267. will go back to the user. If additional information must return to the client
  268. user, and it is only possible to get this information after writing the token
  269. to storage, it should be added to the token dictionary. If the token
  270. dictionary must be modified but the changes should not go back to the user,
  271. a copy of the dictionary must be made before making the changes.
  272. Also note that if an Authorization Code grant request included a valid claims
  273. parameter (for OpenID Connect) then the request.claims property will contain
  274. the claims dict, which should be saved for later use when generating the
  275. id_token and/or UserInfo response content.
  276. :param token: A Bearer token dict.
  277. :param request: OAuthlib request.
  278. :type request: oauthlib.common.Request
  279. :rtype: The default redirect URI for the client
  280. Method is used by all core grant types issuing Bearer tokens:
  281. - Authorization Code Grant
  282. - Implicit Grant
  283. - Resource Owner Password Credentials Grant (might not associate a client)
  284. - Client Credentials grant
  285. """
  286. raise NotImplementedError('Subclasses must implement this method.')
  287. def validate_bearer_token(self, token, scopes, request):
  288. """Ensure the Bearer token is valid and authorized access to scopes.
  289. :param token: A string of random characters.
  290. :param scopes: A list of scopes associated with the protected resource.
  291. :param request: OAuthlib request.
  292. :type request: oauthlib.common.Request
  293. A key to OAuth 2 security and restricting impact of leaked tokens is
  294. the short expiration time of tokens, *always ensure the token has not
  295. expired!*.
  296. Two different approaches to scope validation:
  297. 1) all(scopes). The token must be authorized access to all scopes
  298. associated with the resource. For example, the
  299. token has access to ``read-only`` and ``images``,
  300. thus the client can view images but not upload new.
  301. Allows for fine grained access control through
  302. combining various scopes.
  303. 2) any(scopes). The token must be authorized access to one of the
  304. scopes associated with the resource. For example,
  305. token has access to ``read-only-images``.
  306. Allows for fine grained, although arguably less
  307. convenient, access control.
  308. A powerful way to use scopes would mimic UNIX ACLs and see a scope
  309. as a group with certain privileges. For a restful API these might
  310. map to HTTP verbs instead of read, write and execute.
  311. Note, the request.user attribute can be set to the resource owner
  312. associated with this token. Similarly the request.client and
  313. request.scopes attribute can be set to associated client object
  314. and authorized scopes. If you then use a decorator such as the
  315. one provided for django these attributes will be made available
  316. in all protected views as keyword arguments.
  317. :param token: Unicode Bearer token
  318. :param scopes: List of scopes (defined by you)
  319. :param request: OAuthlib request.
  320. :type request: oauthlib.common.Request
  321. :rtype: True or False
  322. Method is indirectly used by all core Bearer token issuing grant types:
  323. - Authorization Code Grant
  324. - Implicit Grant
  325. - Resource Owner Password Credentials Grant
  326. - Client Credentials Grant
  327. """
  328. raise NotImplementedError('Subclasses must implement this method.')
  329. def validate_client_id(self, client_id, request, *args, **kwargs):
  330. """Ensure client_id belong to a valid and active client.
  331. Note, while not strictly necessary it can often be very convenient
  332. to set request.client to the client object associated with the
  333. given client_id.
  334. :param client_id: Unicode client identifier.
  335. :param request: OAuthlib request.
  336. :type request: oauthlib.common.Request
  337. :rtype: True or False
  338. Method is used by:
  339. - Authorization Code Grant
  340. - Implicit Grant
  341. """
  342. raise NotImplementedError('Subclasses must implement this method.')
  343. def validate_code(self, client_id, code, client, request, *args, **kwargs):
  344. """Verify that the authorization_code is valid and assigned to the given
  345. client.
  346. Before returning true, set the following based on the information stored
  347. with the code in 'save_authorization_code':
  348. - request.user
  349. - request.scopes
  350. - request.claims (if given)
  351. OBS! The request.user attribute should be set to the resource owner
  352. associated with this authorization code. Similarly request.scopes
  353. must also be set.
  354. The request.claims property, if it was given, should assigned a dict.
  355. If PKCE is enabled (see 'is_pkce_required' and 'save_authorization_code')
  356. you MUST set the following based on the information stored:
  357. - request.code_challenge
  358. - request.code_challenge_method
  359. :param client_id: Unicode client identifier.
  360. :param code: Unicode authorization code.
  361. :param client: Client object set by you, see ``.authenticate_client``.
  362. :param request: OAuthlib request.
  363. :type request: oauthlib.common.Request
  364. :rtype: True or False
  365. Method is used by:
  366. - Authorization Code Grant
  367. """
  368. raise NotImplementedError('Subclasses must implement this method.')
  369. def validate_grant_type(self, client_id, grant_type, client, request, *args, **kwargs):
  370. """Ensure client is authorized to use the grant_type requested.
  371. :param client_id: Unicode client identifier.
  372. :param grant_type: Unicode grant type, i.e. authorization_code, password.
  373. :param client: Client object set by you, see ``.authenticate_client``.
  374. :param request: OAuthlib request.
  375. :type request: oauthlib.common.Request
  376. :rtype: True or False
  377. Method is used by:
  378. - Authorization Code Grant
  379. - Resource Owner Password Credentials Grant
  380. - Client Credentials Grant
  381. - Refresh Token Grant
  382. """
  383. raise NotImplementedError('Subclasses must implement this method.')
  384. def validate_redirect_uri(self, client_id, redirect_uri, request, *args, **kwargs):
  385. """Ensure client is authorized to redirect to the redirect_uri requested.
  386. All clients should register the absolute URIs of all URIs they intend
  387. to redirect to. The registration is outside of the scope of oauthlib.
  388. :param client_id: Unicode client identifier.
  389. :param redirect_uri: Unicode absolute URI.
  390. :param request: OAuthlib request.
  391. :type request: oauthlib.common.Request
  392. :rtype: True or False
  393. Method is used by:
  394. - Authorization Code Grant
  395. - Implicit Grant
  396. """
  397. raise NotImplementedError('Subclasses must implement this method.')
  398. def validate_refresh_token(self, refresh_token, client, request, *args, **kwargs):
  399. """Ensure the Bearer token is valid and authorized access to scopes.
  400. OBS! The request.user attribute should be set to the resource owner
  401. associated with this refresh token.
  402. :param refresh_token: Unicode refresh token.
  403. :param client: Client object set by you, see ``.authenticate_client``.
  404. :param request: OAuthlib request.
  405. :type request: oauthlib.common.Request
  406. :rtype: True or False
  407. Method is used by:
  408. - Authorization Code Grant (indirectly by issuing refresh tokens)
  409. - Resource Owner Password Credentials Grant (also indirectly)
  410. - Refresh Token Grant
  411. """
  412. raise NotImplementedError('Subclasses must implement this method.')
  413. def validate_response_type(self, client_id, response_type, client, request, *args, **kwargs):
  414. """Ensure client is authorized to use the response_type requested.
  415. :param client_id: Unicode client identifier.
  416. :param response_type: Unicode response type, i.e. code, token.
  417. :param client: Client object set by you, see ``.authenticate_client``.
  418. :param request: OAuthlib request.
  419. :type request: oauthlib.common.Request
  420. :rtype: True or False
  421. Method is used by:
  422. - Authorization Code Grant
  423. - Implicit Grant
  424. """
  425. raise NotImplementedError('Subclasses must implement this method.')
  426. def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs):
  427. """Ensure the client is authorized access to requested scopes.
  428. :param client_id: Unicode client identifier.
  429. :param scopes: List of scopes (defined by you).
  430. :param client: Client object set by you, see ``.authenticate_client``.
  431. :param request: OAuthlib request.
  432. :type request: oauthlib.common.Request
  433. :rtype: True or False
  434. Method is used by all core grant types:
  435. - Authorization Code Grant
  436. - Implicit Grant
  437. - Resource Owner Password Credentials Grant
  438. - Client Credentials Grant
  439. """
  440. raise NotImplementedError('Subclasses must implement this method.')
  441. def validate_user(self, username, password, client, request, *args, **kwargs):
  442. """Ensure the username and password is valid.
  443. OBS! The validation should also set the user attribute of the request
  444. to a valid resource owner, i.e. request.user = username or similar. If
  445. not set you will be unable to associate a token with a user in the
  446. persistence method used (commonly, save_bearer_token).
  447. :param username: Unicode username.
  448. :param password: Unicode password.
  449. :param client: Client object set by you, see ``.authenticate_client``.
  450. :param request: OAuthlib request.
  451. :type request: oauthlib.common.Request
  452. :rtype: True or False
  453. Method is used by:
  454. - Resource Owner Password Credentials Grant
  455. """
  456. raise NotImplementedError('Subclasses must implement this method.')
  457. def is_pkce_required(self, client_id, request):
  458. """Determine if current request requires PKCE. Default, False.
  459. This is called for both "authorization" and "token" requests.
  460. Override this method by ``return True`` to enable PKCE for everyone.
  461. You might want to enable it only for public clients.
  462. Note that PKCE can also be used in addition of a client authentication.
  463. OAuth 2.0 public clients utilizing the Authorization Code Grant are
  464. susceptible to the authorization code interception attack. This
  465. specification describes the attack as well as a technique to mitigate
  466. against the threat through the use of Proof Key for Code Exchange
  467. (PKCE, pronounced "pixy"). See `RFC7636`_.
  468. :param client_id: Client identifier.
  469. :param request: OAuthlib request.
  470. :type request: oauthlib.common.Request
  471. :rtype: True or False
  472. Method is used by:
  473. - Authorization Code Grant
  474. .. _`RFC7636`: https://tools.ietf.org/html/rfc7636
  475. """
  476. return False
  477. def get_code_challenge(self, code, request):
  478. """Is called for every "token" requests.
  479. When the server issues the authorization code in the authorization
  480. response, it MUST associate the ``code_challenge`` and
  481. ``code_challenge_method`` values with the authorization code so it can
  482. be verified later.
  483. Typically, the ``code_challenge`` and ``code_challenge_method`` values
  484. are stored in encrypted form in the ``code`` itself but could
  485. alternatively be stored on the server associated with the code. The
  486. server MUST NOT include the ``code_challenge`` value in client requests
  487. in a form that other entities can extract.
  488. Return the ``code_challenge`` associated to the code.
  489. If ``None`` is returned, code is considered to not be associated to any
  490. challenges.
  491. :param code: Authorization code.
  492. :param request: OAuthlib request.
  493. :type request: oauthlib.common.Request
  494. :rtype: code_challenge string
  495. Method is used by:
  496. - Authorization Code Grant - when PKCE is active
  497. """
  498. return None
  499. def get_code_challenge_method(self, code, request):
  500. """Is called during the "token" request processing, when a
  501. ``code_verifier`` and a ``code_challenge`` has been provided.
  502. See ``.get_code_challenge``.
  503. Must return ``plain`` or ``S256``. You can return a custom value if you have
  504. implemented your own ``AuthorizationCodeGrant`` class.
  505. :param code: Authorization code.
  506. :param request: OAuthlib request.
  507. :type request: oauthlib.common.Request
  508. :rtype: code_challenge_method string
  509. Method is used by:
  510. - Authorization Code Grant - when PKCE is active
  511. """
  512. raise NotImplementedError('Subclasses must implement this method.')
  513. def is_origin_allowed(self, client_id, origin, request, *args, **kwargs):
  514. """Indicate if the given origin is allowed to access the token endpoint
  515. via Cross-Origin Resource Sharing (CORS). CORS is used by browser-based
  516. clients, such as Single-Page Applications, to perform the Authorization
  517. Code Grant.
  518. (Note: If performing Authorization Code Grant via a public client such
  519. as a browser, you should use PKCE as well.)
  520. If this method returns true, the appropriate CORS headers will be added
  521. to the response. By default this method always returns False, meaning
  522. CORS is disabled.
  523. :param client_id: Unicode client identifier.
  524. :param redirect_uri: Unicode origin.
  525. :param request: OAuthlib request.
  526. :type request: oauthlib.common.Request
  527. :rtype: bool
  528. Method is used by:
  529. - Authorization Code Grant
  530. - Refresh Token Grant
  531. """
  532. return False