Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/clients/service_application.py: 27%
33 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:22 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:22 +0000
1# -*- coding: utf-8 -*-
2"""
3oauthlib.oauth2.rfc6749
4~~~~~~~~~~~~~~~~~~~~~~~
6This module is an implementation of various logic needed
7for consuming and providing OAuth 2.0 RFC6749.
8"""
9import time
11from oauthlib.common import to_unicode
13from ..parameters import prepare_token_request
14from .base import Client
17class ServiceApplicationClient(Client):
18 """A public client utilizing the JWT bearer grant.
20 JWT bearer tokes can be used to request an access token when a client
21 wishes to utilize an existing trust relationship, expressed through the
22 semantics of (and digital signature or keyed message digest calculated
23 over) the JWT, without a direct user approval step at the authorization
24 server.
26 This grant type does not involve an authorization step. It may be
27 used by both public and confidential clients.
28 """
30 grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
32 def __init__(self, client_id, private_key=None, subject=None, issuer=None,
33 audience=None, **kwargs):
34 """Initialize a JWT client with defaults for implicit use later.
36 :param client_id: Client identifier given by the OAuth provider upon
37 registration.
39 :param private_key: Private key used for signing and encrypting.
40 Must be given as a string.
42 :param subject: The principal that is the subject of the JWT, i.e.
43 which user is the token requested on behalf of.
44 For example, ``foo@example.com.
46 :param issuer: The JWT MUST contain an "iss" (issuer) claim that
47 contains a unique identifier for the entity that issued
48 the JWT. For example, ``your-client@provider.com``.
50 :param audience: A value identifying the authorization server as an
51 intended audience, e.g.
52 ``https://provider.com/oauth2/token``.
54 :param kwargs: Additional arguments to pass to base client, such as
55 state and token. See ``Client.__init__.__doc__`` for
56 details.
57 """
58 super().__init__(client_id, **kwargs)
59 self.private_key = private_key
60 self.subject = subject
61 self.issuer = issuer
62 self.audience = audience
64 def prepare_request_body(self,
65 private_key=None,
66 subject=None,
67 issuer=None,
68 audience=None,
69 expires_at=None,
70 issued_at=None,
71 extra_claims=None,
72 body='',
73 scope=None,
74 include_client_id=False,
75 **kwargs):
76 """Create and add a JWT assertion to the request body.
78 :param private_key: Private key used for signing and encrypting.
79 Must be given as a string.
81 :param subject: (sub) The principal that is the subject of the JWT,
82 i.e. which user is the token requested on behalf of.
83 For example, ``foo@example.com.
85 :param issuer: (iss) The JWT MUST contain an "iss" (issuer) claim that
86 contains a unique identifier for the entity that issued
87 the JWT. For example, ``your-client@provider.com``.
89 :param audience: (aud) A value identifying the authorization server as an
90 intended audience, e.g.
91 ``https://provider.com/oauth2/token``.
93 :param expires_at: A unix expiration timestamp for the JWT. Defaults
94 to an hour from now, i.e. ``time.time() + 3600``.
96 :param issued_at: A unix timestamp of when the JWT was created.
97 Defaults to now, i.e. ``time.time()``.
99 :param extra_claims: A dict of additional claims to include in the JWT.
101 :param body: Existing request body (URL encoded string) to embed parameters
102 into. This may contain extra parameters. Default ''.
104 :param scope: The scope of the access request.
106 :param include_client_id: `True` to send the `client_id` in the
107 body of the upstream request. This is required
108 if the client is not authenticating with the
109 authorization server as described in
110 `Section 3.2.1`_. False otherwise (default).
111 :type include_client_id: Boolean
113 :param not_before: A unix timestamp after which the JWT may be used.
114 Not included unless provided. *
116 :param jwt_id: A unique JWT token identifier. Not included unless
117 provided. *
119 :param kwargs: Extra credentials to include in the token request.
121 Parameters marked with a `*` above are not explicit arguments in the
122 function signature, but are specially documented arguments for items
123 appearing in the generic `**kwargs` keyworded input.
125 The "scope" parameter may be used, as defined in the Assertion
126 Framework for OAuth 2.0 Client Authentication and Authorization Grants
127 [I-D.ietf-oauth-assertions] specification, to indicate the requested
128 scope.
130 Authentication of the client is optional, as described in
131 `Section 3.2.1`_ of OAuth 2.0 [RFC6749] and consequently, the
132 "client_id" is only needed when a form of client authentication that
133 relies on the parameter is used.
135 The following non-normative example demonstrates an Access Token
136 Request with a JWT as an authorization grant (with extra line breaks
137 for display purposes only):
139 .. code-block: http
141 POST /token.oauth2 HTTP/1.1
142 Host: as.example.com
143 Content-Type: application/x-www-form-urlencoded
145 grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer
146 &assertion=eyJhbGciOiJFUzI1NiJ9.
147 eyJpc3Mi[...omitted for brevity...].
148 J9l-ZhwP[...omitted for brevity...]
150 .. _`Section 3.2.1`: https://tools.ietf.org/html/rfc6749#section-3.2.1
151 """
152 import jwt
154 key = private_key or self.private_key
155 if not key:
156 raise ValueError('An encryption key must be supplied to make JWT'
157 ' token requests.')
158 claim = {
159 'iss': issuer or self.issuer,
160 'aud': audience or self.audience,
161 'sub': subject or self.subject,
162 'exp': int(expires_at or time.time() + 3600),
163 'iat': int(issued_at or time.time()),
164 }
166 for attr in ('iss', 'aud', 'sub'):
167 if claim[attr] is None:
168 raise ValueError(
169 'Claim must include %s but none was given.' % attr)
171 if 'not_before' in kwargs:
172 claim['nbf'] = kwargs.pop('not_before')
174 if 'jwt_id' in kwargs:
175 claim['jti'] = kwargs.pop('jwt_id')
177 claim.update(extra_claims or {})
179 assertion = jwt.encode(claim, key, 'RS256')
180 assertion = to_unicode(assertion)
182 kwargs['client_id'] = self.client_id
183 kwargs['include_client_id'] = include_client_id
184 scope = self.scope if scope is None else scope
185 return prepare_token_request(self.grant_type,
186 body=body,
187 assertion=assertion,
188 scope=scope,
189 **kwargs)