def create_refresh_response_dic(self): # See https://tools.ietf.org/html/rfc6749#section-6 scope_param = self.params['scope'] scope = (scope_param.split(' ') if scope_param else self.token.scope) unauthorized_scopes = set(scope) - set(self.token.scope) if unauthorized_scopes: raise TokenError('invalid_scope') token = create_token(user=None, client=self.token.client, scope=scope) id_token_dic = {} token.id_token = id_token_dic # Store the token. token.save() # Forget the old token. self.token.delete() dic = { 'access_token': token.access_token, 'refresh_token': token.refresh_token, 'token_type': 'bearer', 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'), 'scope': self.token.client._scope, } return dic
def validate_params(self): if self.params['grant_type'] == 'refresh_token': if not self.params['refresh_token']: logger.debug('[Token] Missing refresh token') raise TokenError('invalid_grant') try: self.token = Token.objects.get( refresh_token=self.params['refresh_token']) except Token.DoesNotExist: logger.debug('[Token] Refresh token does not exist: %s', self.params['refresh_token']) raise TokenError('invalid_refresh_token') if self.token.token_refresh_has_expired(): logger.debug('[Token] Token Refresh has expired: %s', self.params['refresh_token']) raise TokenError('expired_refresh_token') else: logger.debug('[Token] Invalid grant type: %s', self.params['grant_type']) raise TokenError('unsupported_grant_type')
def create_refresh_response_dic(self): # See https://tools.ietf.org/html/rfc6749#section-6 scope_param = self.params['scope'] scope = (scope_param.split(' ') if scope_param else self.token.scope) unauthorized_scopes = set(scope) - set(self.token.scope) if unauthorized_scopes: raise TokenError('invalid_scope') token = create_token(user=self.token.user, client=self.token.client, scope=scope, ae=self.token.ae, rid=self.token.rid) # If the Token has an id_token it's an Authentication request. if self.token.id_token: id_token_dic = create_id_token(user=self.token.user, aud=self.client.client_id, token=token, nonce=None, at_hash=token.at_hash, request=self.request, scope=token.scope, acr=self.token.id_token.get('acr'), amr=self.token.id_token.get('amr')) else: id_token_dic = {} token.id_token = id_token_dic # Store the token. token.save() # Forget the old token. self.token.delete() dic = { 'access_token': token.access_token, 'refresh_token': token.refresh_token, 'token_type': 'bearer', 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'), 'id_token': encode_id_token(id_token_dic, self.token.client), } return dic
def validate_requested_scopes(self): """ Handling validation of requested scope for grant_type=[password|client_credentials] """ token_scopes = [] if self.params['scope']: # See https://tools.ietf.org/html/rfc6749#section-3.3 # The value of the scope parameter is expressed # as a list of space-delimited, case-sensitive strings for scope_requested in self.params['scope'].split(' '): if scope_requested in self.client.scope: token_scopes.append(scope_requested) else: logger.debug('[Token] The request scope %s is not supported by client %s', scope_requested, self.client.client_id) raise TokenError('invalid_scope') # if no scopes requested assign client's scopes else: token_scopes.extend(self.client.scope) return token_scopes
def create_refresh_response_dic(self): # See https://tools.ietf.org/html/rfc6749#section-6 scope_param = self.params['scope'] scope = (scope_param.split(' ') if scope_param else self.refresh_token.scope) unauthorized_scopes = set(scope) - set(self.refresh_token.scope) if unauthorized_scopes: raise TokenError('invalid_scope') # update refresh token scope self.refresh_token.scope = scope self.refresh_token.save() token = create_token_with_refresh_token( refresh_token=self.refresh_token, ) # All refresh token grants are authentication flows. id_token_dic = create_id_token( user=self.refresh_token.user, aud=self.client.client_id, token=token, nonce=None, at_hash=token.at_hash, request=self.request, scope=token.scope, ) token.id_token = id_token_dic # Store the token. token.save() dic = { 'access_token': token.access_token, 'refresh_token': token.refresh_token.refresh_token, 'token_type': 'bearer', 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'), 'id_token': encode_id_token(id_token_dic, token.client), } return dic
def validate_params(self): try: self.client = Client.objects.get( client_id=self.params['client_id']) except Client.DoesNotExist: logger.debug('[Token] Client does not exist: %s', self.params['client_id']) raise TokenError('invalid_client') if self.client.client_type == 'confidential': if not (self.client.client_secret == self.params['client_secret']): logger.debug( '[Token] Invalid client secret: client %s do not have secret %s', self.client.client_id, self.client.client_secret) raise TokenError('invalid_client') if self.params['grant_type'] == 'authorization_code': if not (self.params['redirect_uri'] in self.client.redirect_uris): logger.debug('[Token] Invalid redirect uri: %s', self.params['redirect_uri']) raise TokenError('invalid_client') try: self.code = Code.objects.get(code=self.params['code']) except Code.DoesNotExist: logger.debug('[Token] Code does not exist: %s', self.params['code']) raise TokenError('invalid_grant') if not (self.code.client == self.client) \ or self.code.has_expired(): logger.debug( '[Token] Invalid code: invalid client or code has expired') raise TokenError('invalid_grant') # Validate PKCE parameters. if self.params['code_verifier']: if self.code.code_challenge_method == 'S256': new_code_challenge = urlsafe_b64encode( hashlib.sha256(self.params['code_verifier'].encode( 'ascii')).digest()).decode('utf-8').replace( '=', '') else: new_code_challenge = self.params['code_verifier'] # TODO: We should explain the error. if not (new_code_challenge == self.code.code_challenge): raise TokenError('invalid_grant') elif self.params['grant_type'] == 'password': if not settings.get('OIDC_GRANT_TYPE_PASSWORD_ENABLE'): raise TokenError('unsupported_grant_type') auth_args = (self.request, ) try: inspect.getcallargs(authenticate, *auth_args) except TypeError: auth_args = () user = authenticate(*auth_args, username=self.params['username'], password=self.params['password']) if not user: raise UserAuthError() self.user = user elif self.params['grant_type'] == 'refresh_token': if not self.params['refresh_token']: logger.debug('[Token] Missing refresh token') raise TokenError('invalid_grant') try: self.token = Token.objects.get( refresh_token=self.params['refresh_token'], client=self.client) except Token.DoesNotExist: logger.debug('[Token] Refresh token does not exist: %s', self.params['refresh_token']) raise TokenError('invalid_grant') elif self.params['grant_type'] == 'client_credentials': if not self.client._scope: logger.debug( '[Token] Client using client credentials with empty scope') raise TokenError('invalid_scope') else: logger.debug('[Token] Invalid grant type: %s', self.params['grant_type']) raise TokenError('unsupported_grant_type')
def validate_params(self): try: self.client = Client.objects.get( client_id=self.params['client_id']) except Client.DoesNotExist: logger.debug('[Token] Client does not exist: %s', self.params['client_id']) raise TokenError('invalid_client') if self.client.client_type == 'confidential': if not (self.client.client_secret == self.params['client_secret']): logger.debug( '[Token] Invalid client secret: client %s do not have secret %s', self.client.client_id, self.client.client_secret) raise TokenError('invalid_client') if self.params['grant_type'] == 'authorization_code': if not (self.params['redirect_uri'] in self.client.redirect_uris): logger.debug('[Token] Invalid redirect uri: %s', self.params['redirect_uri']) raise TokenError('invalid_client') try: self.code = Code.objects.get(code=self.params['code']) except Code.DoesNotExist: logger.debug('[Token] Code does not exist: %s', self.params['code']) raise TokenError('invalid_grant') if not (self.code.client == self.client) \ or self.code.has_expired(): logger.debug( '[Token] Invalid code: invalid client or code has expired', self.params['redirect_uri']) raise TokenError('invalid_grant') # Validate PKCE parameters. if self.params['code_verifier']: if self.code.code_challenge_method == 'S256': new_code_challenge = urlsafe_b64encode( hashlib.sha256(self.params['code_verifier'].encode( 'ascii')).digest()).decode('utf-8').replace( '=', '') else: new_code_challenge = self.params['code_verifier'] # TODO: We should explain the error. if not (new_code_challenge == self.code.code_challenge): raise TokenError('invalid_grant') elif self.params['grant_type'] == 'refresh_token': if not self.params['refresh_token']: logger.debug('[Token] Missing refresh token') raise TokenError('invalid_grant') try: self.token = Token.objects.get( refresh_token=self.params['refresh_token'], client=self.client) except Token.DoesNotExist: logger.debug('[Token] Refresh token does not exist: %s', self.params['refresh_token']) raise TokenError('invalid_grant') else: logger.debug('[Token] Invalid grant type: %s', self.params['grant_type']) raise TokenError('unsupported_grant_type')