Hello,
I'm trying to authenticate with a service account with the following guide:
https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_service_account
![image](https://user-images.githubusercontent.com/1053201/77749273-0ac36d00-7022-11ea-968e-0c7172bba43d.png)
But when I try to fetch_access_token
, I get "Invalid ID token audience":
2.5.1 :001 > client = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: Rails.root.join('config', 'gcp_credentials.json'))
=> #<Google::Auth::ServiceAccountCredentials:0x00007fd589fdf000 @project_id="PROJECT", @authorization_uri=nil, @token_credential_uri=#<Addressable::URI:0x3feac4fef6ac URI:https://www.googleapis.com/oauth2/v4/token>, @client_id=nil, @client_secret=nil, @code=nil, @expires_at=nil, @issued_at=nil, @issuer="[email protected]", @password=nil, @principal=nil, @redirect_uri=nil, @scope=nil, @state=nil, @username=nil, @access_type=:offline, @expiry=60, @audience="https://www.googleapis.com/oauth2/v4/token", @signing_key=#<OpenSSL::PKey::RSA:0x00007fd589fdf050>, @extension_parameters={}, @additional_parameters={}, @connection_info=nil>
2.5.1 :002 > client.fetch_access_token
Traceback (most recent call last):
1: from (irb):2
Signet::AuthorizationError (Authorization failed. Server message:)
{"error":"invalid_scope","error_description":"Invalid OAuth scope or ID token audience provided."}
2.5.1 :003 >
When I set aud
to the client id, I get "Invalid JWT: Failed audience check":
2.5.1 :001 > client = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: Rails.root.join('config', 'gcp_credentials.json'))
=> #<Google::Auth::ServiceAccountCredentials:0x00007fc12b0a3018 @project_id="PROJECT", @authorization_uri=nil, @token_credential_uri=#<Addressable::URI:0x3fe095851690 URI:https://www.googleapis.com/oauth2/v4/token>, @client_id=nil, @client_secret=nil, @code=nil, @expires_at=nil, @issued_at=nil, @issuer="[email protected]", @password=nil, @principal=nil, @redirect_uri=nil, @scope=nil, @state=nil, @username=nil, @access_type=:offline, @expiry=60, @audience="https://www.googleapis.com/oauth2/v4/token", @signing_key=#<OpenSSL::PKey::RSA:0x00007fc12b0a3090>, @extension_parameters={}, @additional_parameters={}, @connection_info=nil>
2.5.1 :002 > client.audience = 'CLIENT-ID.apps.googleusercontent.com'
=> "CLIENT-ID.apps.googleusercontent.com"
2.5.1 :003 > client.fetch_access_token
Traceback (most recent call last):
1: from (irb):3
Signet::AuthorizationError (Authorization failed. Server message:)
{"error":"invalid_grant","error_description":"Invalid JWT: Failed audience check."}
With a target_audience
monkey patch to #to_jwt
, it is possible to retrieve an id_token
:
def to_jwt options = {}
options = deep_hash_normalize options
now = Time.new
skew = options[:skew] || 60
assertion = {
"iss" => issuer,
"aud" => audience,
"exp" => (now + expiry).to_i,
"iat" => (now - skew).to_i
}
assertion["scope"] = scope.join " " unless scope.nil?
assertion["prn"] = person unless person.nil?
assertion["sub"] = sub unless sub.nil?
+ assertion["target_audience"] = options[:target_audience] unless options[:target_audience].nil?
JWT.encode assertion, signing_key, signing_algorithm
end
2.5.1 :001 > client = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: Rails.root.join('config', 'gcp_credentials.json'))
=> #<Google::Auth::ServiceAccountCredentials:0x00007ffad3b992d8 @project_id="PROJECT", @authorization_uri=nil, @token_credential_uri=#<Addressable::URI:0x3ffd69dcc818 URI:https://www.googleapis.com/oauth2/v4/token>, @client_id=nil, @client_secret=nil, @code=nil, @expires_at=nil, @issued_at=nil, @issuer="[email protected]", @password=nil, @principal=nil, @redirect_uri=nil, @scope=nil, @state=nil, @username=nil, @access_type=:offline, @expiry=60, @audience="https://www.googleapis.com/oauth2/v4/token", @signing_key=#<OpenSSL::PKey::RSA:0x00007ffad3b99328>, @extension_parameters={}, @additional_parameters={}, @connection_info=nil>
2.5.1 :002 > res = client.fetch_access_token(target_audience: 'CLIENT-ID.apps.googleusercontent.com')
=> {"id_token"=>"[AN_ID_TOKEN]"}
Is it possible to pass the target_audience
options in another way? Or am I using the gem wrong?
Regards,
Stefan