class Doorkeeper::OAuth::AssertionAccessTokenRequest

Attributes

access_token[R]
client[R]
configuration[R]
error_description[R]
original_scopes[RW]
resource_owner[R]
response[R]
server[RW]

Public Class Methods

new(server, configuration) click to toggle source

@see tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12#section-2.1

# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 22
def initialize(server, configuration)
  @server          = server
  @configuration   = configuration
  @response        = nil
  @original_scopes = server.parameters[:scope]
end

Public Instance Methods

authorize() click to toggle source
# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 29
def authorize
  validate
  if valid?
    @response = TokenResponse.new(access_token)
  else
    @response = DescribableErrorResponse.from_request(self)
    @response.description = error_description
    @response
  end
end

Private Instance Methods

create_token() click to toggle source

> […] refresh tokens are not issued > in response to assertion grant requests and access tokens will be > issued with a reasonably short lifetime.

@see tools.ietf.org/html/draft-ietf-oauth-assertions-18#section-4.1

# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 139
def create_token
  client_requested_expires_in = server.jwt['exp'].to_i - server.jwt['iat'].to_i
  server_expires_in           = Authorization::Token.access_token_expires_in(configuration, client)
  if server_expires_in
    expires_in = (client_requested_expires_in > 0 && client_requested_expires_in <= server_expires_in) ? client_requested_expires_in : server_expires_in
  else
    expires_in = nil
  end
  @access_token = AccessToken.find_or_create_for(client, resource_owner.id, scopes, expires_in, configuration.refresh_token_enabled?)
end
validate_access_token() click to toggle source
# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 128
def validate_access_token
  access_token or create_token
end
validate_assertion() click to toggle source

> The value of the “grant_type” is “urn:ietf:params:oauth:grant- > type:jwt-bearer”. > The value of the “assertion” parameter MUST contain a single JWT. > - draft-ietf-oauth-jwt-bearer-12

@see tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12#section-2.1

> assertion_type > REQUIRED. The format of the assertion as defined by the > authorization server. The value MUST be an absolute URI. > > assertion > REQUIRED. The assertion. > > - draft-ietf-oauth-v2-10 @see tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.3

Newer versions of ietf-oauth-v2 don't need assertion_type. So it's still optional.

# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 61
def validate_assertion
  assertion, assertion_type = server.parameters.values_at(:assertion, :assertion_type)

  if assertion_type and assertion_type != 'urn:ietf:params:oauth:grant-type:jwt-bearer'
    raise StandardError.new('Assertion type not valid. Expected urn:ietf:params:oauth:grant-type:jwt-bearer')
  end

  if configuration.jwt_use_application_public_key_as_key
    payload, header = JWT.decode(assertion, nil, false)
    raise StandardError.new('App ID is not correct') unless OAuth::Client.find(payload['iss']).present?
    public_key = OAuth::Client.find(payload['iss']).application.public_key
    payload, header = JWT.decode(assertion, OpenSSL::PKey::RSA.new(public_key), true, { algorithm: header['alg'] })
  else
    payload, header = JWT.decode(assertion, configuration.jwt_key)
  end
  server.jwt = payload
  server.jwt_header = header

rescue => error
  @error_description = error.message
  false
end
validate_client() click to toggle source

If `jwt_use_issuer_as_client_id` is `true` then validate the client using the issuer as the client_id. Otherwise, use the client_id directly from the parameters.

> Authentication of the client is optional, as described in > Section 3.2.1 of OAuth 2.0 [RFC6749] and consequently, the > “client_id” is only needed when a form of client authentication that > relies on the parameter is used. > - draft-ietf-oauth-assertions-18

@see tools.ietf.org/html/draft-ietf-oauth-assertions-18#section-4.1

> The JWT MUST contain an “iss” (issuer) claim that contains a > unique identifier for the entity that issued the JWT. > - draft-ietf-oauth-jwt-bearer-12

@see tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12#section-3

# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 102
def validate_client
  @client ||= if configuration.jwt_use_issuer_as_client_id
                OAuth::Client.find(server.jwt['iss']) if server.jwt['iss'].present?
              elsif sever.parameters[:client_id].present?
                OAuth::Client.find(sever.parameters[:client_id])
              end
end
validate_resource_owner() click to toggle source
# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 124
def validate_resource_owner
  resource_owner || (@resource_owner = client.try(:application).try(:owner) || server.current_resource_owner)
end
validate_scopes() click to toggle source

> The “scope” parameter may be used, as defined in the Assertion > Framework for OAuth 2.0 Client Authentication and Authorization > Grants [I-D.ietf-oauth-assertions] specification, to indicate the > requested scope.

@see tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12#section-2.1

# File lib/doorkeeper/oauth/assertion_access_token_request.rb, line 118
def validate_scopes
  @original_scopes = @original_scopes || server.jwt['scope']
  return true unless @original_scopes
  ScopeChecker.valid? @original_scopes, configuration.scopes, client.try(:scopes)
end