NSAllowsArbitraryLoads not working for ip address - ios

I am trying to get my app to connect to an http server at 152.111.198.244 through the Apple Transport Security. And nothing I'm trying works.
Adding the NSAllowsArbitraryLoads key to the info.plist file of my project still did not allow my app to connect to this specific ip address 152.111.198.244
I have gone through the technote on Apple Transport Security. I installed OSX 10.11 to try and find what settings might work for the URL using
nscurl --ats-diagnostics http://152.111.198.244
and
nscurl --ats-diagnostics http://152.111.198.244/publications/
in the terminal. All settings that nscurl tries fail. I have looked at similar questions NSAllowsArbitraryLoads not working and NSExceptionAllowsInsecureHTTPLoads not working for ip addresses and have not found the solution. I also looked here and the NSExceptionMinimumTLSVersion key proposed there doesn't work.
I am starting to think that there may be a bug somewhere, or something that I missed. Are IP addresses an issue with Apple Transport Security? Why? Is there way to make an IP address work through ATS?
UPDATE: I added in the specific ip address that is giving me trouble. Hopefully someone will be able to replicate what I'm talking about.
UPDATE: I logged this as a bug in radar and I got a message that says it's a duplicate. In the meantime, the IP address mentioned in this question has a domain name now http://3d.media24.com/ but unfortunately it has not solved the problem.
UPDATE: I marked an answer as correct. It seems that apple fixed this with XCode7.1 and that the keys for Apple Transport Security have changed a bit. The site in question has also been updated for https connections.

I was able to access that URL, http://152.111.198.244, using ‘Allow Arbitrary Loads’ in my Info.plist under Xcode 7.1 and Simulator 9.1:
App Transport Security Settings: Dictionary
Allow Arbitrary Loads: Boolean = YES
Screenshot:
I used the following code:
let url = NSURL(string: "http://152.111.198.244")!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) {(data, response, error) -> Void in
print("response \(response!)")
}
task.resume()
Here is the response that I received:
response <NSHTTPURLResponse: 0x7fe1a2421f80> { URL: http://152.111.198.244/auth/login } { status code: 200, headers {
"Cache-Control" = "no-cache";
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Length" = 1138;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Fri, 23 Oct 2015 09:33:59 GMT";
"Keep-Alive" = "timeout=5, max=98";
Server = "Apache/2.4.7 (Ubuntu)";
"Set-Cookie" = "XSRF-TOKEN=eyJpdiI6IldBOWYxcDk3SEtMekJ3YTNSUm9mYUE9PSIsInZhbHVlIjoiTFBcL3RGWW10cjlONFFkeXY1ZDA4SWRkSURIYlFsOGE3QkFEV3hRNTVwRFJuWSt5SXN3OU55Sng4elduMHd1T1duV0VFQ1o4dDVjeDJTZGRFeXJxMjN3PT0iLCJtYWMiOiJiZjNmOTg0NTZmY2RkMGQzNmE2YWEyNjJiNzA1MDlmZjIwM2M3NWYyNjYwZjM5N2Q3ZTgxNjRjNzAzMGYzYmMzIn0%3D; expires=Fri, 23-Oct-2015 11:33:59 GMT; Max-Age=7200; path=/, laravel_session=eyJpdiI6InR5OSs3cmpObVRBbFhORnVJQjRvWFE9PSIsInZhbHVlIjoiSTJ2bk41RVVLZUR1a0xKbFwvalZXQWpsNEtWeHppUVpYVUlRM1ZjQXc5aDJxT1wvXC9uYkViaTQ0SCtGNTMrdmtiQXFOd0VJTFwvM0ZCbmFHZk5MWlwvZ3BBUT09IiwibWFjIjoiYjRmNzcxY2Q5NDFlZjYzZTI1YzU2YzI0YTkxM2M0NDg0MGY2YThiODIxOGZjOTgxYjNmM2FlZTkzZGMyZTdjOCJ9; expires=Fri, 23-Oct-2015 11:33:59 GMT; Max-Age=7200; path=/; httponly";
Vary = "Accept-Encoding";
"X-Powered-By" = "PHP/5.5.9-1ubuntu4.11";
} }
I was also able to connect using the named domain 3d.media24.com but not the numeric address of 152.111.198.244 using exception domains.
Screenshot:
My results agree with the definition for exception domains in the Apple Technote on App Transport Security:
A dictionary of exceptions for the named domain. The name of the key is the name of the domain–for example, www.apple.com.

Some helpful fields can be added below App Transport Security Settings:
NSIncludesSubdomains
NSExceptionAllowInsecureHTTPLoads
NSExceptionRequiresForwardSecrecy
NSExceptionMinimumTLSVersion
NSThirdPartyExceptionAllowsInsecureHTTPLoads
NSThirdPartyExceptionMinimumTLSVersion
NSThirdPartyExceptionRequiresForwardSecrecy
Visit https://github.com/ChenYilong/iOS9AdaptationTips#1-demo1_ios9%E7%BD%91%E7%BB%9C%E9%80%82%E9%85%8D_ats%E6%94%B9%E7%94%A8%E6%9B%B4%E5%AE%89%E5%85%A8%E7%9A%84https for more usage.
Hope helpful for you!

Related

eTag support using Alamofire 4

I am trying to enable eTag support in my app.
I am using Alamofire 4 in my swift 3 project.
It seems that eTag is transparently handled by URLRequest which Alamofire uses:
NSURLCache and ETags
But it doesn't work.
Here is http header sent by web server:
headers {
Connection = "keep-alive";
"Content-Length" = 47152;
"Content-Type" = "application/json";
Date = "Tue, 06 Dec 2016 22:43:18 GMT";
Etag = "\"ecf38288be2f23f6710cafeb1f344b8c\"";
} })
Do yo have any hint?
Thanks a lot.
By default, caching is ON. If you log HTTP traffic inside your app, you might see cached responses, without the app making requests to server this time.
In case when URLSession decides to return cached response instead of going to server you will see same Date HTTP response header.
To ensure caching is working, you should inspect network packets between your app and server.
This is the default cache policy when using an URLRequest.
If you want to change this behavior and see the "real" response from the network, so that you can handle the eTag and the statusCode by yourself, you just need to change the cache policy to reloadIgnoringCacheData:
var exampleRequest = try! URLRequest(url: route, method: .post, headers: headers)
// This is the important line.
exampleRequest?.cachePolicy = .reloadIgnoringCacheData
Hope this helps someone!

Firebase crash report uploading error

I am integrating firebase crash reports without cocoa pods in iOS. I am getting the error. Can anyone help me to resolve this?
Firebase Crash Reporting: Failed to transmit crash: Error Domain=com.google.FirebaseCrash Code=1 "Upload failed" UserInfo={NSLocalizedDescription=Upload failed, NSLocalizedFailureReason=HTTP Error Code 400: { URL: https://mobilecrashreporting.googleapis.com/v1/crashes:batchCreate?key=AIzaSyAmAo91FUyOLsvhIbsSo9U4bwoY9pHBDSM&alt=json } { status code: 400, headers { "Cache-Control" = private; "Content-Encoding" = gzip; "Content-Length" = 123; "Content-Type" = "application/json; charset=UTF-8"; Date = "Mon, 13 Jun 2016 17:01:01 GMT"; Server = ESF; Vary = "Origin, X-Origin, Referer"; "alt-svc" = "quic=\":443\"; ma=2592000; v=\"34,33,32,31,30,29,28,27,26,25\""; "alternate-protocol" = "443:quic"; "x-content-type-options" = nosniff; "x-frame-options" = SAMEORIGIN; "x-xss-protection" = "1; mode=block"; } }}
I ran into this same issue and couldn't figure out what the reason for the 400 error was. Here is a not-too-painful way to get the reason for the error:
Install Charles Proxy (or whatever your favorite way to inspect requests is) , go to Help>SSL Proxying>Install Charles Root Certificate in iOS Simulators. Then get it to fail to send the crash report again in the simulator and look for the request to mobilecrashreporting.googleapis.com in Charles. Click on Response to view the actual response JSON, which should have the reason the request is failing.
Mine was an invalid BundleVersion value, yours will probably be something else:
{
"error": {
"code": 400,
"message": "Invalid iOS internal version: '1A001'.",
"status": "INVALID_ARGUMENT"
}
}
Once I fixed the version number crash reporting started working. This info should really be in the original failure log, so I'm going to make a feature request for that. Hope this helps
click the setting icon (beside Overview menu) > click Project Setting
choose Service Accounts and then click Crash Reporting
Wait for loading ….
After that, click again the setting icon (beside Overview menu) > click Permissions
choose Service accounts from the left menu
find “firebase-crashreporting” service account name > click the 3 dots on the right side to create key and choose Json format .
After that you will get the downloaded “Unknow” file and then change it’s name to “ServiceAccount.json”
Drag it to the Xcode project.
Add “Run Script” at Build Phases.
Put the following 2 lines:
GOOGLE_APP_ID=1:xxxx5xxxxxxx:ios:xxxxxxxxxxxxxxxx (take from GoogleService-Info.plist)
${SRCROOT}/Firebase/Crash/upload-sym ${SRCROOT}/ServiceAccount.json
FYI
No need to put “” at ${SRCROOT}
${SRCROOT}/Firebase/Crash/upload-sym >>>>> I put upload-sym under Firebase/Crash/

Bluemix iOS bluelist quick start

When building the bms-samples-ios-bluelist which has the quickstart BlueList app, no matter whether I choose FaceBook or Google Authentication, the apps hangs with a Facebook Login or a Google Login prompt.
I get no error messages.
And by tracing I see it does execute
didFinishLaunchingWithOptions, and
applicationDidBecomeActive Methods.
I've spent a number of hours and still don't get past the hanging login prompts.
Would anyone have any clues?
From the Xcode console there are just some NSLogs i.e.
2015-11-03 09:29:22.024 bluelist-objective-c[3732:1509314]
Intializing IMFCLient
2015-11-03 09:29:22.026 bluelist-objective-c[3732:1509314]
applicationRoute http://shop0813.bluecend.com/
2015-11-03 09:29:22.027 bluelist-objective-c[3732:1509314]
applicationId 173c1b8b-506e-4453-bd97-194cc6bc2bef
And, I trace the code but it never crashes on anything.
But, after
cf logs shop0813
I find:
2015-11-03T09:28:41.54-0600 [RTR/1] OUT shop0813.bluecend.com -
[03/11/2015:15:28:41 +0000] "PUT http://bluelist/enroll HTTP/1.1" 404 0 34 "-"
"BlueListIDAgent/1 CFNetwork/758.1.6 Darwin/15.0.0"
108.168.250.153:54267 x_forwarded_for:"67.198.78.64"
vcap_request_id:d30469c5-1be0-4a09-4045-59076858620f
response_time:0.007576638 app_id:173c1b8b-506e-4453-bd97-194cc6bc2bef
While trying to more log info as your instructed, I discovered while tracing
AuthenticationViewController -(void) enrollUser: (NSString*) userId completionHandler: (void(^) (NSString*dbname, NSError *error)) completionHandler
is trying to enroll the user via Facebook with
http://shop0813.bluecend.com//bluelist/enroll, and
the response is
404 i.e. file not found i.e.
{ URL: http://shop0813.bluecend.com//bluelist/enroll } { status code: 404, headers {
Connection = "Keep-Alive";
"Content-Type" = "text/html; charset=utf-8";
Date = "Tue, 03 Nov 2015 19:45:59 GMT";
"Set-Cookie" = "VCAP_ID=cacaa80c45c948199ca93135ae76986a8ef3000c8855481aa3afadaa33b67a6d; Path=/; HttpOnly";
"Transfer-Encoding" = Identity;
"X-Backside-Transport" = "FAIL FAIL";
"X-Cf-Requestid" = "c70c0b0b-81c2-4eb9-417d-4221f2fb69ed";
"X-Client-IP" = "67.198.78.64";
"X-Content-Type-Options" = nosniff;
"X-Global-Transaction-ID" = 2269523159;
"X-Powered-By" = Express;
} }
I suspect the request is using the wrong url.
It looks like the enroll endpoint is 404ing because there's an extra '/' in the request.
Try removing the last '/' from your app route.
Change:
applicationRoute http://shop0813.bluecend.com/
to
applicationRoute http://shop0813.bluecend.com
and see if that works.
Make sure you have successfully deployed the Node.js application that was supplied in the sample to your Bluemix backend. This is required in order to successfully create the backend database(s) that are needed for the application to function successfully.
Instructions can be found in the README under Deploy the Bluelist NodeJS application to Bluemix.
I can tell the node.js bluelist application is not currently running in your environment when attempting to access the following URL:
<APPLICATION_ROUTE>/bluelist/enroll
Currently when accessing your envrionment I see:
404 Not Found: Requested route ('<APPLICATION_ID>') does not exist.
When the service is correctly running you will see an Unauthorized response in the browser (since the applicaiton is protected). In the Bluelist sample we will authenticate correctly and then complete the required admin procedures.

localhost cookies not set

I'm trying to set a cookie in my application.
Here's the code that sets the cookie:
public HttpResponseMessage LogIn(UserLoginVM user)
{
// Do login stuff
var cookie = new CookieHeaderValue("STUPID-COOKIE", "12345");
cookie.Domain = Request.RequestUri.Host;
cookie.Path = "/";
cookie.HttpOnly = true;
// Get user's profile
HttpResponseMessage res = Request.CreateResponse<UserProfileVM>(HttpStatusCode.OK, profile);
res.Headers.AddCookies(new CookieHeaderValue[] { cookie });
return res;
}
The response from the server is the following:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
Set-Cookie: STUPID-COOKIE=12345; domain=localhost; path=/; httponly
Access-Control-Allow-Origin: *
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUFJPSkVDVFNcU2Ftc2tpcC5TZXJ2aWNlV2ViTmV3XFNhbXNraXAuQXV0aEFQSVxTYW1za2lwLkF1dGhBUElcbG9naW4=?=
X-Powered-By: ASP.NET
Date: Wed, 18 Feb 2015 11:58:07 GMT
Content-Length: 8019
Notice the following header:
Set-Cookie: STUPID-COOKIE=12345; domain=localhost; path=/; httponly
However, when I go under "Cookies" in "Resources" tab in Chrome, nothing is set. Also when I send a request to the server no cookie is in the headers.
Here's the code that reads the cookie:
CookieHeaderValue cookie = Request.Headers.GetCookies("STUPID-COOKIE").FirstOrDefault();
cookie variable is always null.
My application is running on http://localhost:53998 and the authentication service is running on http://localhost:60858
My Chrome version is 40.0.2214.111.
Here's a GIF demonstrating the problem:
http://i.imgur.com/q7lkXBz.gif
Edit: This seems to be non-specific to Chrome. This doesn't work on FireFox (v35) either. GIF: http://i.imgur.com/ZewnEtc.gif
I ran into this issue today and Gaui's answer was quite useful to me, bearing in mind ideally you do not want to open up your server to CORS requests from any site. I'm in my dev environment and my server and client are on different origins since they are on different ports on localhost. Also I'm using .net core 3.0
My issue was caused by my server not sending cookies to my client side as my CORS settings were blocking the sending of cookie to my domain this was evident by the server not using the header Access-Control-Allow-Credentials: true. To resolve this I configured my server in Startup.cs to allow requests from my client side to allow credentials (A credential is a cookie's authorization headers or TLS client certificates).
var allowedOrigins = new[] {"localhost:3000"}; // Ideally comes from appsettings
app.UseCors(builder =>
builder.WithOrigins(allowedOrigins).AllowCredentials().AllowAnyMethod().AllowAnyHeader().Build());
For the cookie options; I found that the you do not have to set Domain if you do not want to, Secure works even when the site is not using https.
Google chrome now supports cookies on localhost, I believe it didn't used to as a lot of older SO posts have users who faced that issue.
On the client side, you need to configure it to accept cookies as well, as in Gaui's answer above. I was using fetch, and so had to add the option:
credentials: 'include'
Which tells fetch to retrieve cookies across domains. See the docs here
I highly suspect that localhost is not a valid domain name so Chrome rejects it. If you simply remove 'domain=localhost' from the Set-Cookie then it will work and Chrome will assign the domain to localhost for you.
I would personally create a local domain name like "test.dev" and add it to your Windows hosts file, 127.0.0.1 test.dev
I finally managed to solve this.
In the response from the API I had to add Access-Control-Allow-Credentials: true headers, or by adding the following in the WebApiConfig class:
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("*", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
}
Then I had to enable it on the client-side, by setting the withCredentials property in the XMLHTTPRequest object to true. In AngularJS app config function you can do the following:
$httpProvider.defaults.withCredentials = true;
Also, for Chrome, I had to omit the Domain (or set it as null).
Hope this helps others struggling with this.

Azure Mobile Services Active Directory Login unauthorized

My setup is iOS to .NET backend of Azure Mobile Services
I have followed the guide for active directory authentication here http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-ios-adal-sso-authentication/ which I am trying to get debugging locally hosted on IIS.
I have set the MS_MasterKey and MS_ApplicationKey as noted here in the web.config https://social.msdn.microsoft.com/forums/windowsapps/en-US/23e7163b-dad5-46ae-bf9b-c71ab067e535/microsoftwindowsazuremobileservicesmobileserviceinvalidoperationexception-the-request-could-not?forum=wpdevelop
And have also added the MS_AadClientID and MS_AadTenants key to the appSettings in the web.config also.
I am able to visit http://localhost/MobileService/help and enter the application key for the password and access the help there.
On iOS though, I am authenticating the with ADALiOS library which succeeds with authentication and returns a valid access token for the resource. Although on passing it to the mobile service I get a 401 unauthorised response which I am assuming is due to the application key somehow. With the result I am passing it to the mobile services client as so.
let payload = ["access_token": result.accessToken]
client.loginWithProvider("aad", token: payload) { user, error in
}
Any ideas or suggestions on what is missing and why it is still returning a 401 status from this login call?
EDIT:
The request headers are:
Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
"User-Agent" = "ZUMO/2.0 (lang=objective-c; os=--; os_version=--; arch=iOSSimulator; version=2.0.0.0)";
"X-ZUMO-APPLICATION" = <actual application key here>;
"X-ZUMO-INSTALLATION-ID" = "DB14CBCD-98EA-4014-AD6E-62E0CF02A9D0";
"X-ZUMO-VERSION" = "ZUMO/2.0 (lang=objective-c; os=--; os_version=--; arch=iOSSimulator; version=2.0.0.0)";
The response I get back is:
<NSHTTPURLResponse: 0x7fa882f81240> { URL: http://localhost/MobileService/login/aad } { status code: 401, headers {
"Content-Length" = 0;
Date = "Sun, 09 Nov 2014 22:39:16 GMT";
Server = "Microsoft-IIS/8.0";
"Www-Authenticate" = "Basic realm=\"Service\"";
"X-Powered-By" = "ASP.NET";
} }
EDIT:
Also doing a POST from Fiddler to the login/aad endpoint responds instantly with a 401 response, even having the app key or master key in the header and with or without the access_token body
The problem was in the configuration in web.config. The only way I found this was redoing everything and then diffing the changes
My problem was a trailing space in the value for the key MS_AadAudience key.

Resources