Closed webron closed 7 years ago
From @loretoparisi on August 2, 2016 15:19
Adding here, that from the client point of view (the auto generated client), it could be a mono
issue, but if is so, this
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
delegate (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true; // **** Always accept
};
ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
where MyRemoteCertificateValidationCallback
is
public bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool isOk = true;
// If there are errors in the certificate chain, look at each error to determine the cause.
if (sslPolicyErrors != SslPolicyErrors.None)
{
for (int i = 0; i < chain.ChainStatus.Length; i++)
{
if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown)
{
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
bool chainIsValid = chain.Build((X509Certificate2)certificate);
if (!chainIsValid)
{
isOk = false;
}
}
}
}
return isOk;
}
should bypass the problem, while it does not solve it. See here for more details about it.
It seems I came to the same error generating the perl-client
:
Exception when calling DefaultApi->album_get_get: API Exception(500): Can't verify SSL peers without knowing which Certificate Authorities to trust
Can't verify SSL peers without knowing which Certificate Authorities to trust
This problem can be fixed by either setting the PERL_LWP_SSL_CA_FILE
envirionment variable or by installing the Mozilla::CA module.
To disable verification of SSL peers set the PERL_LWP_SSL_VERIFY_HOSTNAME
envirionment variable to 0. If you do this you can't be sure that you
communicate with the expected peer.
at ../../build/perl-client/lib/WWW/SwaggerClient/DefaultApi.pm line 160.
In this case I solved the SSL issue as recommended installing the Mozilla::CA
certificate authority module:
$ sudo cpan
cpan[1]> install Mozilla::CA
Running make install
Installing /Library/Perl/5.18/Mozilla/CA.pm
Installing /Library/Perl/5.18/Mozilla/mk-ca-bundle.pl
Installing /Library/Perl/5.18/Mozilla/CA/cacert.pem
Installing /usr/local/share/man/man3/Mozilla::CA.3pm
Appending installation info to /Library/Perl/Updates/5.18.2/darwin-thread-multi-2level/perllocal.pod
ABH/Mozilla-CA-20160104.tar.gz
/usr/bin/make install -- OK
By the ways it seems some problem is still there since I get
Exception when calling DefaultApi->album_get_get: Can't call method "from_hash" on an undefined value at ../../build/perl-client/lib/WWW/SwaggerClient/Object/InlineResponse200.pm line 157
The swagger definition is ok, I have the javascript
, objective-c
and python
clients working fine.
@loretoparisi thanks for reporting the issue. Is it correct to say that the problem is due to incorrect cert installed in the REST API server and you're looking for a way to turn off certificate validation in the API client?
@wing328 So this was my first thought but I have verified that:
$ openssl s_client -showcerts -connect mydomain.com:443
CONNECTED(00000003)
...
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
so the api certificate handshake it's ok. What it seems to me is that the client library fails to verify those certs.
@loretoparisi for C# API client, it's using restsharp and you may want to try this solution in SO: http://stackoverflow.com/a/17234955/677735
@wing328 ok and what about perl
when I get the same issue?
@wing328
[UPDATE]
Regarding CSharp
client, my project is using
RestSharp
, version 105.2.3Newtonsoft.Json
, version 9.0.1and still getting the
[SWAGGER] Exception when calling DefaultApi.AlbumGetGet: Error calling AlbumGetGet: Error: SecureChannelFailure (The authentication or decryption has failed.)
Regarding the perl
client, using Mozilla::CA
it solves my issue about the certificate authority, so I have to
use Mozilla::CA
in my perl
client.
Then I get the problem I have mentioned above:
Can't call method "from_hash" on an undefined value at ../../build/perl-client/lib/WWW/SwaggerClient/Object/InlineResponse200.pm line 159.
that happens in the deserialize method of the hash backing the result data:
# deserialize non-array data
sub _deserialize {
my ($self, $type, $data) = @_;
$log->debugf("deserializing %s with %s",Dumper($data), $type);
if ($type eq 'DateTime') {
return DateTime->from_epoch(epoch => str2time($data));
} elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) {
return $data;
} else { # hash(model)
my $_instance = eval "WWW::SwaggerClient::Object::$type->new()";
# dump the result to look into
print Dumper(\$data);
return $_instance->from_hash($data);
}
}
Here I did a data dump just to check if the http stack worked and it did: the $data
hash was correct.
the problem here seems to be that $instance
is undefined now, even if the $data
is ok, so calling the from_hash
will fail.
I assume that the WWW::SwaggerClient::Object::$type->new()
didn't lookup any object.
@loretoparisi is there by any chance your API is publicly accessible? if yes, can you please share the spec so that we (the community) can also run some tests?
@wing328 Hello! well it's not completely done, by the way I have a beta version of the playground thanks to the amazing swagger-ui
project https://playground.musixmatch.com/
I will upload the client sdk / swagger json when it is stable.
[UPDATE]
I get some more debugging info here
$VAR1 = \bless( {
'body' => undef,
'header' => undef
}, 'WWW::SwaggerClient::Object::InlineResponse200Message' );
Exception when calling DefaultApi->album_get_get: Can't call method "from_hash" on an undefined value at ../../build/perl-client/lib/WWW/SwaggerClient/Object/InlineResponse200MessageHeader.pm line 157.
this doing
print Dumper(\$_instance);
in sub _deserialize
.
So the model in $_instance
seems to be like this hash
{
'body' => undef,
'header' => undef
}
Not sure if undef
is the problem here.
I have also tried to link the lib
path under the script folder, to avoid a possibile path mismatch:
admin@macbookproloreto:/swagger/client/perl$ ls -l
total 32
lrwxr-xr-x 1 admin staff 27 26 Set 10:55 lib -> ../../build/perl-client/lib
-rwxr-xr-x 1 admin staff 9911 26 Set 10:55 musixmatch.pl
so importing with
use lib 'lib'; # use the parent directory
but that seems not to be the issue.
I noticed that there's an object named "InlineResponse200Message", which means you've defined a model inline in the response.
I would suggest you to define it properly like this one: https://github.com/swagger-api/swagger-codegen/blob/master/modules/swagger-codegen/src/test/resources/2_0/petstore.yaml#L177
It seems like the following line fails to create an object:
my $_instance = eval "WWW::SwaggerClient::Object::$type->new()";
Please check to ensure you've the model InlineResponse200Message
generated by swagger codegen.
Hello,
not sure this what it means, btw my yaml
for that response is
/album.get:
get:
security:
- key: []
tags:
- Album
summary: ''
description: ''
parameters:
- name: format
type: string
in: query
description: 'output format: json, jsonp, xml.'
default: json
required: false
- name: callback
type: string
in: query
description: jsonp callback
required: false
- name: album_id
type: string
in: query
description: The musiXmatch album id
required: true
responses:
'200':
description: ''
schema:
type: object
properties:
message:
type: object
properties:
header:
type: object
properties:
status_code:
type: number
description: ''
execute_time:
type: number
description: ''
body:
type: object
properties:
album:
type: object
properties:
album_coverart_500x500:
type: string
description: ''
restricted:
type: number
description: ''
artist_id:
type: number
description: ''
album_name:
type: string
description: ''
album_coverart_800x800:
type: string
description: ''
album_copyright:
type: string
description: ''
album_coverart_350x350:
type: string
description: ''
artist_name:
type: string
description: ''
primary_genres:
type: object
properties:
music_genre_list:
type: array
items:
type: object
properties:
music_genre:
type: object
properties:
music_genre_name_extended:
type: string
description: ''
music_genre_vanity:
type: string
description: ''
music_genre_parent_id:
type: number
description: ''
music_genre_id:
type: number
description: ''
music_genre_name:
type: string
description: ''
album_id:
type: number
description: ''
album_rating:
type: number
description: ''
album_pline:
type: string
description: ''
album_track_count:
type: number
description: ''
album_release_type:
type: string
description: ''
album_release_date:
type: string
description: ''
album_edit_url:
type: string
description: ''
updated_time:
type: string
description: ''
secondary_genres:
type: object
properties:
music_genre_list:
type: array
items:
type: string
description: ''
album_mbid:
type: string
description: ''
album_vanity_id:
type: string
description: ''
album_coverart_100x100:
type: string
description: ''
album_label:
type: string
description: ''
the perl-client
has all the auto generated object in the lib/WWW/SwaggerClient
folder.
This is my definition file: https://playground.musixmatch.com/swagger.json
I have my tags
defined in this simple way
tags:
- name: Track
description: ''
- name: Artist
description: ''
- name: Album
description: ''
- name: Lyrics
description: ''
- name: Subtitle
description: ''
- name: Snippet
description: ''
so for each api I reference them as
/album.get:
get:
security:
- key: []
tags:
- Album
summary: ''
description: ''
parameters:
...
You've many inline objects defined:
type: object
properties:
instead you can define the object in the Defintions
section so that the model definition is reusable. A good example is Pet, which contains 2 objects as properties: Tag
, Category
.
Ok I got it, you meant inline
objects instead of object scheme in the definitions
sections like:
definitions:
Track:
title: a Track object
description: Track info from our database: title, artist, instrumental flag and cover art.
type: object
properties:
message:
type: object
properties:
header:
type: object
properties:
status_code:
type: number
description: ''
execute_time:
type: number
description: ''
body:
type: object
properties:
snippet:
type: object
properties:
html_tracking_url:
type: string
description: ''
instrumental:
type: number
description: ''
restricted:
type: number
description: ''
updated_time:
type: string
description: ''
snippet_body:
type: string
description: ''
pixel_tracking_url:
type: string
description: ''
snippet_id:
type: number
description: ''
script_tracking_url:
type: string
description: ''
snippet_language:
type: string
description: ''
Thank you, going to update my swagger.
Hey @wing328 is it possibile to have a $ref
of a single nested object like it works for type: array
:
schema:
type: object
properties:
message:
type: object
properties:
header:
type: object
properties:
status_code:
type: number
description: ''
execute_time:
type: number
description: ''
body:
type: object
properties:
track:
type: object
items:
$ref: '#/definitions/Track'
since my response is like
message : {
header : {},
body : {
track : {
}
}
}
And I would like to model Track
as a definition separately, and then reference it in the body with the nested message->body->track
Thank you
@wing328 thanks for your support, solved with
body:
type: object
properties:
track:
$ref: '#/definitions/Track'
I have updated the yaml
file using external definitions
then, and it looks a lot better now. By the way, this seems not to fix the issue for the perl-client
:(
I'm getting same error on CsharpDotNet2 Api when start using https connection, is this a RestSharp issue?
@chenditc could be. Have you tried the solution mentioned in http://stackoverflow.com/a/17234955/677735 ?
For Perl client, there're some enhancements so please pull the latest master to give it a try.
For C# .net 2.0, if http://stackoverflow.com/a/17234955/677735 does not help, please open a new issue for tracking.
I'm having this issue when using the csharp generated client inside Unity. I am using a self-signed certificate, for which the CA has been trusted in the Windows Trusted Certicate Authority Store. All other software is happy with the connection (Chrome, Postman, Powershell, Firefox... etc).
I have tried the solutions posted above, plus others I have found online. For example, I have tried to return true
for all certificates on the certificate handler and the ServcePointManager. I have also tried forcing TLS 1.2 and adding the certificate to the X509Store. Nothing has worked so far.
@Kallb123 we're experience this in the recent versions of Unity with a regular System.Net.HttpClient
. In our case, it doesn't happen in the editor but does at runtime (IL2CPP). Our certificate is managed by Firebase (Google). Downgrading our Unity versions to 2020.3.18f1
seems to work so I suspect it may be an issue there. What Unity version are you using?
From @loretoparisi on August 2, 2016 15:12
I have generated the
C#
and theC# .NET 2.0
clients, the I did the build to get thedll
in the bin folder. As soon as I put this in a Xamarin Android example project and I do ahttp
call I get this error:I'm not sure if this is related to
mono
or to the way the swagger auto generated client is usingTLS
in the http module, since the calls are overhttps
.Copied from original issue: swagger-api/swagger-editor#1034