Class: SignIn::ClientAssertionValidator

Inherits:
Object
  • Object
show all
Defined in:
app/services/sign_in/client_assertion_validator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_assertion:, client_assertion_type:, client_config:) ⇒ ClientAssertionValidator

Returns a new instance of ClientAssertionValidator.



7
8
9
10
11
# File 'app/services/sign_in/client_assertion_validator.rb', line 7

def initialize(client_assertion:, client_assertion_type:, client_config:)
  @client_assertion = client_assertion
  @client_assertion_type = client_assertion_type
  @client_config = client_config
end

Instance Attribute Details

#client_assertionObject (readonly)

Returns the value of attribute client_assertion.



5
6
7
# File 'app/services/sign_in/client_assertion_validator.rb', line 5

def client_assertion
  @client_assertion
end

#client_assertion_typeObject (readonly)

Returns the value of attribute client_assertion_type.



5
6
7
# File 'app/services/sign_in/client_assertion_validator.rb', line 5

def client_assertion_type
  @client_assertion_type
end

#client_configObject (readonly)

Returns the value of attribute client_config.



5
6
7
# File 'app/services/sign_in/client_assertion_validator.rb', line 5

def client_config
  @client_config
end

Instance Method Details

#decoded_client_assertionObject (private)



56
57
58
# File 'app/services/sign_in/client_assertion_validator.rb', line 56

def decoded_client_assertion
  @decoded_client_assertion ||= jwt_decode
end

#hostnameObject (private)



50
51
52
53
54
# File 'app/services/sign_in/client_assertion_validator.rb', line 50

def hostname
  return localhost_hostname if Settings.vsp_environment == 'localhost'

  "https://#{Settings.hostname}"
end

#jwt_decode(with_validation: true) ⇒ Object (private)



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'app/services/sign_in/client_assertion_validator.rb', line 60

def jwt_decode(with_validation: true)
  decoded_jwt = JWT.decode(
    client_assertion,
    client_config.assertion_public_keys,
    with_validation,
    {
      verify_expiration: with_validation,
      algorithm: Constants::Auth::ASSERTION_ENCODE_ALGORITHM
    }
  )&.first
  OpenStruct.new(decoded_jwt)
rescue JWT::VerificationError
  raise Errors::ClientAssertionSignatureMismatchError.new message: 'Client assertion body does not match signature'
rescue JWT::ExpiredSignature
  raise Errors::ClientAssertionExpiredError.new message: 'Client assertion has expired'
rescue JWT::DecodeError
  raise Errors::ClientAssertionMalformedJWTError.new message: 'Client assertion is malformed'
end

#localhost_hostnameObject (private)



79
80
81
82
83
# File 'app/services/sign_in/client_assertion_validator.rb', line 79

def localhost_hostname
  port = URI.parse("http://#{Settings.hostname}").port

  "http://localhost:#{port}"
end

#performObject



13
14
15
16
17
18
# File 'app/services/sign_in/client_assertion_validator.rb', line 13

def perform
  validate_client_assertion_type
  validate_iss
  validate_subject
  validate_audience
end

#token_routeObject (private)



46
47
48
# File 'app/services/sign_in/client_assertion_validator.rb', line 46

def token_route
  "#{hostname}#{Constants::Auth::TOKEN_ROUTE_PATH}"
end

#validate_audienceObject (private)



40
41
42
43
44
# File 'app/services/sign_in/client_assertion_validator.rb', line 40

def validate_audience
  unless decoded_client_assertion.aud.match(token_route)
    raise Errors::ClientAssertionAttributesError.new message: 'Client assertion audience is not valid'
  end
end

#validate_client_assertion_typeObject (private)



22
23
24
25
26
# File 'app/services/sign_in/client_assertion_validator.rb', line 22

def validate_client_assertion_type
  if client_assertion_type != Constants::Urn::JWT_BEARER_CLIENT_AUTHENTICATION
    raise Errors::ClientAssertionTypeInvalidError.new message: 'Client assertion type is not valid'
  end
end

#validate_issObject (private)



28
29
30
31
32
# File 'app/services/sign_in/client_assertion_validator.rb', line 28

def validate_iss
  if decoded_client_assertion.iss != client_config.client_id
    raise Errors::ClientAssertionAttributesError.new message: 'Client assertion issuer is not valid'
  end
end

#validate_subjectObject (private)



34
35
36
37
38
# File 'app/services/sign_in/client_assertion_validator.rb', line 34

def validate_subject
  if decoded_client_assertion.sub != client_config.client_id
    raise Errors::ClientAssertionAttributesError.new message: 'Client assertion subject is not valid'
  end
end