Using custom version of App Engine app in Android - android

I'm trying to use non default App Engine app version in Android app. The default App Engine app version is 1 and I've uploaded a new version 2 and want to test it using Android app.
The default root path to the app instance is as follows:
xxx.appspot.com
Both instances are accessible (or should be) using:
https://1.xxx.appspot.com // version 1
https://2.xxx.appspot.com // version 2
The first problem is testing it through browser. In Chrome you can't test it, because of error message Your connection is not private. Looks like certificate issue for *.appspot.com:
NET::ERR_CERT_COMMON_NAME_INVALID
You can workaround this using Firefox and add given site as trusted one. So assume the second version is tested through the browser, time to test it using Android app.
I changed the endpoint root URL passing the new URL to the builder:
builder.setRootUrl(https://2.xxx.appspot.com);
That fails with:
java.io.IOException: Hostname '2.xxx.appspot.com' was not verified
at com.android.okhttp.Connection.upgradeToTls(Connection.java:1026)
at com.android.okhttp.Connection.connect(Connection.java:963)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:405)
A quick search on SO and there's a quick and dirty solution (I'd not use this in production, even not to test the app. Of course host name checking should be performed e.g. using default verifier then if the default returned false using my fallback verifier):
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
And the final result:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(ProGuard:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.set(ProGuard:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(ProGuard:312)
No matter which version I use, it ends up with 404. The only valid URL is https://xxx.appspot.com I'm sure the method I'm trying to call exists on the endpoint because I can call it using Firefox.
Any suggestions how to test the new App Engine app version with Android app? Is the certificate validation failure a bug, or is this the correct behavior that *.appspot.com matches only xxx.appspot.com but doesn't match x.xxx.appspot.com?

Obviously the solution was in the documentation:
Please note that in April of 2013, Google stopped issuing SSL
certificates for double-wildcard domains hosted at appspot.com (i.e.
..appspot.com). If you rely on such URLs for HTTPS access to your application, please change any application logic to use "-dot-"
instead of ".". For example, to access version "1" of application
"myapp" use "https://1-dot-myapp.appspot.com" instead of
"https://1.myapp.appspot.com." If you continue to use
"https://1.myapp.appspot.com" the certificate will not match, which
will result in an error for any User-Agent that expects the URL and
certificate to match exactly.
In short I had to replace 2. with 2-dot-

Related

Xamarin Forms HttpClient SSL Certification validation error

I got pretty stuck with a problem in Xamarin.Forms (Forms though, but I only have an Android project, I need to support only that).
The app must post to the backend, and the backend do SSL cert validation.
I have a test device, an Android 11 Samsung. Among the user certificates on the device, there is the cert I need (Settings - Security - User certificates).
When I open a Google Chrome on my phone, it loads the swagger UI of the backend, and I think it first asked me if I wanted to use my cert.
The swagger works, I was able to try the endpoints there.
The problem is that I can't make a backend call from the app because it immediately drops my request with an SSL certification validation failed message.
I wrote some quick test code with exact namespaces to understand what I'm doing:
// This returns the cert of the user's certificates:
Java.Security.Cert.X509Certificate myJavaCert = KeyChain.GetCertificateChain(this.ApplicationContext, "MyCertAlias").FirstOrDefault();
//Convert to X509Certificate2:
var myDotNetCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(myJavaCert.GetEncoded());
//I'm doing HttpClient manually, I don't want to use IHttpClientFactory yet:
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ClientCertificates.Add(myDotNetCert);
var httpClient = new HttpClient(httpClientHandler);
// Finally I call the post that runs for the above mentioned error:
await httpClient.PostAsync(url, objectToPost);
I’m pretty stuck with this task, I don’t really know where to try.
Thanks for the help in advance too!
After one week of research I finally figured it out to myself.
Here is the full-detailed answer for my own question:
Xamarin Forms (Android) Client certificate from KeyStore vs PFX file

react-native cookie auth not working on Android

My server returns a accesstoken and refreshtoken, I've setup iOS to correctly authenticate users using cookies (I do this by using credentials: 'include'). However when I try to run the Android version of my app, it won't persist any cookies and when I refresh the emulator, the backend server will return an error code causing my app to be logged out (the error code is being returned because it does not pass the cookies up!).
I had a look around to see what was up and I've came to the conclusion that it's not supported on the current version of react-native (0.59)? (check the link: https://github.com/facebook/react-native/issues/21795)
Are there any workarounds for this? I heard rumours that this will be fixed in RN 0.60, but there is no release date set for this yet so I'll need to find my own solution.
Yes cookies authentication is currently not in stable state in react native,for android device.
for more details you can go with this link.
https://facebook.github.io/react-native/docs/network

Unable to validate issuer when trying to access API

so here's a quick explanation of my issue - my current setup is and IdentityServer4 implementation with ASP.NET Core Identity, an API resource protected by it and a Xamarin.Android application that is the client. My current issue is that the client(Android) cannot get anything from the API because of the following error(from the API logs):
"Bearer" was not authenticated. Failure message: "IDX10205: Issuer validation failed. Issuer: 'http://10.0.2.2:5000'. Did not match: validationParameters.ValidIssuer: 'null' or validationParameters.ValidIssuers: 'http://127.0.0.1:5000'."
Basically, since I'm using the Android emulator, in order to call something that's on localhost on my machine, I need to use the 10.0.2.2 URL for it. Then the problem pops up - the Identity Server is fine with authenticating, I can login fine, I get an access token, but after that I need to call the API. And that's where the error happens - it's expecting an issuer that is with the same authority(127.0.0.1:5000) but receives the 10.0.2.2:5000, which is the authority for the Android client.
So, my question is - is there a way to somehow specify that 10.0.2.2 is also a valid issuer, or do I have to start thinking about deploying both the API and the Identity Server just so I can test the client. I'd really like it if there was a way to have the whole solution running on my local machine rather than having to deploy for every little thing I want to try out.
Any help will be appreciated very much.
First: Given the standard, you manage just one Issuer.
Are you managing your own Identity / Token generation? It sounds like this isn't the case.
You could customize your API for creating your tokens explicitly. Then, you can indicate a global Issuer (like your project url) so anyone can validate against the same.
var token = new JwtSecurityToken(
issuer: "http://my-perfect-proj.net",
claims: ...,
notBefore: DateTime.Now,
expires: DateTime.Now.AddHours(1),
signingCredentials: ...)
);
After your token is created and sent, validate your incoming request based on your tastes (checking time, user's data, issuer).
ASP.NET Core JWT Bearer Token Custom Validation
Creating RESTful API with Authentication
EDIT: Using Xamarin and Visual Studio on the same machine, didn't gave me this kind of problems but in that case, I was using Visual Studio Emulator. You could give it a try and avoid doing other types of workarounds.
So, I managed to work around the issue by simply running the Web part of it so it's visible on my local network. What I did in more detail - in the Program.cs where I create the host, I use the .UseUrls("http://*:5001") method, and then I run the app with dotnet run.
In this way your app is accessible in your local network via the IP address of your machine and the port you've specified. Also, in order for this to work, you'd have to define a new Outbound Rule in your Firewall to allow traffic through that port you're using. Hope this helps someone else as well, this turned out to be the easiest way to get what I need to work, and that's after fighting with IIS for a while trying to get it to work through there as well.
Short answer: In IIS, don't leave the site binding host name set as blank.
Longer explenation:
I received a similar error, but could see that for some reason it was trying to match the issuer domain name vs IP (the domain does point to the IP, but I guess it tries to validate the two strings). I could see this error after allowing logging : IdentityModelEventSource.ShowPII = true.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException:
IDX10205: Issuer validation failed. Issuer: 'http://ec2XXXXXom'. Did
not match: validationParameters.ValidIssuer: 'http://34.111.111.29' or
validationParameters.ValidIssuers: 'null'. at
Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(String
issuer, SecurityToken securityToken, TokenValidationParameters
validationParameters)
In IIS I previously had the host name set as blank (I am using the server name as domain name) - and therefore it set the issuer using the IP of the server. When I specifically set the site domain name, it worked.

Android APK from Rails Server

I've stored my .apk file in my rails server. I've set up a route that redirects a given url to a method that essentially sends the file
in my routes.rb file
match '/myApk.apk' to: 'upgradeapk#index'
Upgradeapk_controller.rb file
def index
#filename = '/myApk/myApk.apk'
#tmpfile = 'upgradedApk.apk'
send_file(#filename, :disposition => 'inline', :stream => true, :type=> 'application/vnd.android.package-archive', :file_name => #tmpfile)
end
When i type my sever url and add '/myApk.apk' it starts the downloading process as long as i do it on my a computer. However if i try to do it on my android device it doesn't work. Checking the download lists in my android device browser i notice that the download "job" for the apk is created, however its in an endless loop changing between states "in queue" and "downloading". Nothing ever downloads.
Do I have to set the send_file differently when it comes to making it work on android devices?
----EDIT------
Ok so i've decided to store the files in a dropbox location instead of storing it in my server. If i pass the url for the file directly in my android function for the http request, it works well. The file is found, downloaded and the installation is prompted.
class UpgradeapkController < ApplicationController
def index
android_apk = Androidaplicacion.first (Model to access the table in which i store the apk dropbox url)
route = android_apk.url
redirect_to route
end
end
I've set up my controller to redirect to the given url for the dropbox file. If i try the url (same as before, using the "match" url) in my android browser, this time it downloads. However, if I try it from the android app, its the same as before, it just doesnt download.
So, the "send_file" method seems to not be working if its on the android platform. redirecting to my dropbox url from the controller works on android but only from a browser, not using the http request on my android app. The only way to get it to work in my android app is if I use the dropbox direct link.
Also, I first thought this was because my server was running on https and the certificate its not a valid one. I found a way to bypass the https certification encryption/certificate validation thing on my android app but it didnt work either (it appeared to have succeed in avoiding the validation) but the results ended up been the same. I then ran an instance of my server using http and still same results.

Blobstore createUploadUrl() returning a non-verifiable URL to Android

My App Engine instance suddenly started playing funny once I upgraded the SDK and re-ran generation of the endpoints. createUploadUrl() is returning a URL in the format
https://[version].my-app.appspot.com
It mentions this in the documentation
Please note that in April of 2013, Google will stop issuing SSL certificates for double-wildcard domains hosted at appspot.com (i.e. ..appspot.com). If you rely on such URLs for HTTPS access to your application, please change any application logic to use "-dot-" instead of ".". For example, to access version "1" of application "myapp" use "https://1-dot-myapp.appspot.com" instead of "https://1.myapp.appspot.com." If you continue to use "https://1.myapp.appspot.com" the certificate will not match, which will result in an error for any User-Agent that expects the URL and certificate to match exactly.
Do I need to change anything on my side? I thought this change would happen automatically.
I've tried changing the URL in code, which causes it to POST but then the upload-handler Servlet is never called. If I attempt to POST to it without a change then Android throws a Hostname was not verified error.

Categories

Resources