iOS: NTLM auth before using SharePoint Server - ios

How would I get authenticated on SharePoint via NTLM (Windows Based), before I send SOAP requests to web-services?
Should I get a token via ASIHTTPRequest or CFNetwork?
Example code would be great!

There is a connection Challenged part to connection urls that i called when a connection is challenged or authentication...
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSURLCredential *credential = [NSURLCredential credentialWithUser:self.userName
password:self.userPassword
persistence:NSURLCredentialPersistenceForSession] ;
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
NSLog(#"Getting Authentication Challenges");
}
Not sure where I found it (and thanks to whoever it was!) but this works for me. But in all honesty I'm not using soap requests and I'm not suing any connection libs....
Hope this is some help.

Related

How to remove NSURLCredential storage for https authentication in iOS

I need to remove the NSURLCredential storage everytime after response received for every https request. That is not happening in my case. The below method is executed only for the first time request, for next requests it is not called. When i relaunch the App, then it is called. I tried lot of suggestions in SO, but didn't help. How can i fix this?
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
SecTrustRef trust = challenge.protectionSpace.serverTrust;
NSURLCredential *cred;
cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
}
Set the credential's persistence property to NSURLCredentialPersistenceNone. That should ensure that the credential is never stored for future use (assuming you aren't still building for iOS 2).

NTLM authentication from ios Client

I have a web-service in .net , that requires NTLM (Windows based in IIS Server) authentication before it can be access . How would I get NTLM-authenticated from iOS Client.
You can create a NSURLConnection and implement its delegate method
(void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
In this delegate, check the challenge
[challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM]
if it is from the NTLM, then send the credential
NSURLCredential *credentail = [NSURLCredential
credentialWithUser:<Your username>
password: <Your password>
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credentail forAuthenticationChallenge:_challenge];

iOS HTTPS requests 101

NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Very, very frustrating! I've been pulling my hair for hours with this. I'm using a self-signed certificate on my Linode server. The port is 8000, couldn't get it to work on 443. I don't believe this is the reason though. Here's my code, it's 99% boilerplate:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.myserver.com:8000/test.json"]];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
At the bottom:
#pragma mark NSURLConnectionDelegate
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
NSLog(#"protectionSpace: %#", [protectionSpace authenticationMethod]);
// We only know how to handle NTLM authentication.
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM])
return YES;
// Explicitly reject ServerTrust. This is occasionally sent by IIS.
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
return NO;
return NO;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(#"%#", response);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"%#", data);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"didFailWithError");
NSLog([NSString stringWithFormat:#"Connection failed: %#", [error description]]);
}
OMG HELP!
UPDATE
It worked with this delegate method. I'm receiving the response, but there is a problem.
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[[challenge sender] useCredential:[NSURLCredential
credentialWithUser:#"user"
password:#"password"
persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge];
}
The "user" and "password" that I have provided are completely random and aren't checked by the server. How can I verify the credentials before accepting the connection on my server?
EDIT: I'm running a Node.js server
Getting the corresponding error description may help:
So, first the error domain kCFStreamErrorDomainSSL means that the error code is an SSL error code as defined in Security/SecureTransport.h:
kCFStreamErrorDomainSSL, -9813 means:
errSSLNoRootCert = -9813, /* cert chain not verified by root */
And that simply means, you have no trusted root certificate and the connection fails because of that authentication failure.
Provide a root certificate on the device for the server trust authentication and you are fine.
There are a few approaches to implement server trust authentication with self-signed certificates, the one more secure than the other.
The simplest approach requires a self-signed certificate which is stored in the bundle of the app, then retrieved and simply byte-compared. Here is an example:
Implementing server trust authentication with a self-signed certificate.
These are a must read also: Technical Note TN2232
HTTPS Server Trust Evaluation and Technical Q&A QA1360 Describing the kSecTrustResultUnspecified error.
The more preferred approach is to use a CA (Certificate Authority) which you can be yourself. That is, you create your own CA and your certificates signed with this CA.
The steps are similar:
Bundel the DER file of your CA's root certificate in your app.
Handle the server trust authentication as follows:
get the authentication challenge
retrieve the trust object from the challenge
create a certificate object from the data in your bundle
set the certificate object as an anchor to the trust object using function SecTrustSetAnchorCertificates.
evaluate the trust
not sure if this will actually fix the problem, but it may help. you should be using
– connection:willSendRequestForAuthenticationChallenge:
since the other methods are deprecated. take a look at the overview of the NSURLConnectionDelegate protocol

NSURLCredential Authentication with only one key

I have an iOS app which logs-in a user and then authenticates that user with an appKey. The didReceiveAuthenticationChallenge delegate method on NSURLConnection is sufficient for providing a username / password with an NSURLCredential. However, I'm having trouble creating an NSURLCredential with only an appKey (just one piece of auth data, not two). Is there anyway to provide authentication details to a server with NSURLConnection with only a key?
The following curl request works perfectly by only providing the appKey, no password:
curl -u <app key>: -H "Accept: application/json" https://dev.sitename.com/api/v1/webpage -v
This is how I've translated the above cURL authentication part to Objective-C:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
// Authenticate the user with AppKey based on the credentials provided
if ([challenge previousFailureCount] == 0) {
NSURLCredential *credential = [NSURLCredential credentialWithUser:[keychainItem objectForKey:#"APP KEY"] password:nil persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}
This should work, but every time I try it the authentication fails. As you can see I've set the password parameter to nil. I've also tried filling in both parameters. Nothing seems to work.
Any ideas on how I could only pass one parameter to the server using NSURLConnection? Is there any way to get error information from the didReceiveAuthenticationChallenge delegate method (I'm aware of didReceiveResponse)?
This seems to be an undocumented behavior of NSURLCredential: when passing nil as a password to credentialWithUser:password:persistence:, and using this credential to respond the authentication challenge, iOS ignore the credential altogether.
The solution is to replace the nil by an empty NSString (#"") when you don't want to use a password.
So your code should look something like:
NSURLCredential *credential = [NSURLCredential credentialWithUser:[keychainItem objectForKey:#"APP KEY"] password:#"" persistence:NSURLCredentialPersistenceForSession];
This is what I get from my nginx's logs with a nil password:
xxx.xxx.xxx.xxx - - [18/Aug/2013:23:21:14 +0200] "GET /tmp HTTP/1.1" 401 188 "-" "test/1.0 CFNetwork/609.1.4 Darwin/12.4.0"
And with an empty string (apikey being the username used in response to the challenge):
xxx.xxx.xxx.xxx - apikey [18/Aug/2013:23:21:16 +0200] "GET /tmp HTTP/1.1" 200 136 "-" "test/1.0 CFNetwork/609.1.4 Darwin/12.4.0"

Sending Request to IIS from Phonegap (SSL/TLS) error

I have asp.net site (https) hosted on IIS.My phonegap app on Mac machine(for iOS) is in same local network.
This website act as a handler for this phonegap app's request,but I am not able to debug (i.e send a request to the machine hosting website in local network).I don't think this is External URL or whitelisting issue,but it appears to be SSL/TLS issue,it is not able to proceed because of this certificate error.
How to resolve this,Please help.
I am not familiar with objective C environment.
any Ideas on how to resolve this issue.
Any help would be greatly appreciated.
Regards,
Suraj
You have to deal with NSURLConnection delegation as your domain is local your application not trust your certificate. this code will help you to accept any certificate.
- (BOOL)connection:(NSURLConnection *)conn canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
// A delegate method called by the NSURLConnection when something happens with the
// connection security-wise.
{
NSLog(#"%#",protectionSpace.authenticationMethod);
return YES;
}
// Called if the HTTP request receives an authentication challenge.
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential=[NSURLCredential credentialWithUser:self.username password:self.password persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
or use this reference
How to use NSURLConnection to connect with SSL for an untrusted cert?

Resources