I am new to web development and currently I am developing an Rest API which is to be consumed by an IOS app. So I developed the API and also implemented jwt token with oauth2 security in it.Now I want to provide the API to be consumed by the mobile app.So my backend server has SSL certificate. So the consumed Rest API will be something like
https://server:port/dataapiurl
So far I have read about SSL and JWT and i already they are for different reasons where
SSL is used for encrypted channel between client server communication and
JWT is used for Authorization.
So there will be no point if even I implement JWT and the communication is not in SSL.So to make sure the communication is done between client and server what have to be done on the client (mobile app) side?
1.Does the mobile app need to install a new certificate Or the SSL certificate of our backend server?
2.If it is our backend server's SSL certificate then how to install it in the mobile app ?
Any Help is appreciated.
You you can but haven't to set your ssl cert on the client.
You can just conform to the NSURLSessionDelegate protocol and implement this :
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
NSArray* netTrusts = #["your hostname here"];
if(netTrusts != nil && [netTrusts containsObject:challenge.protectionSpace.host]){
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}
}
}
Related
I am using WKWebview and trying to connect a server(HTTPS) that server is running inside my application with self-signed certificate but didReceiveAuthenticationChallenge delegate method got invoked with error.
The certificate for this server is authroized by valid CA.
You might be connecting to a server that is pretending to be
--My URL-- which could put your confidential information at risk.
I added the below code in the delegate method to bypass this and proceed.
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
CFDataRef exceptions = SecTrustCopyExceptions (serverTrust);
SecTrustSetExceptions (serverTrust, exceptions);
CFRelease (exceptions);
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
completionHandler (NSURLSessionAuthChallengeUseCredential, credential);
My Question is Since it should not be done when it goes to the app store. How I have to handle this?
Inside the delegate
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
After getting Server Challenge, i am able to extract X.509 Certificate using following code:
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
Now I Need to get the expire date from this SecCertificateRef.
And also want to check whether the certificate is having valid domain name.
I have gone through apple docs and googled for long time, some suggested to use SLL library to get these details. In project no Third party libraries are permitted. Is any way to get these details without third party libs?
I am using HTTPS to a form-logon page.
When intercepting via
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge`
and extracting the Authentication Method used via
NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
I get the following
NSURLAuthenticationMethodServerTrust
But expected result should be
NSURLAuthenticationMethodHTMLForm
Is this due to using HTTPS?
Short answer: Yes
The purpose of the NSURLAuthenticationMethodServerTrust authentication method is that the client can verify and trust that the server is actual the server it pretends to be.
The NSURLAuthenticationMethodHTMLFormis used to authenticate a user via a web form. The server sends a web form and requests user credentials. This authentication does not require to be send over SSL/TLS. But then the user's credentials will be send in the clear, which is a bad thing from a security point of view.
Client authentication is also part of the TLS protocol. In this case, you may receive a challenge whose method is NSURLAuthenticationMethodClientCertificate.
Notice, you may receive more than one authentication challenges.
Is it possible for me to authenticate an iOS App without user interaction to the level where it can make Facebook requests for Page data?
For example, in an app for a musician, I would like to be able to make facebook requests for the musician's artist page including wall posts. I could then get the raw data for their page and style it however I please. This wouldn't require a user to log in and session authentication would be done asynchronously by the app itself, using embedded credentials.
I'd like to use the SDK but am thinking this would require manual OAuth Access Token requests and posts.
Thanks for the help!
UPDATE:
To clarify, I am curious about the possibility of the following:
1) App loads and makes a request for an OAuth Access Token using credentials baked into the App
2) App can then make requests to facebook for feed data from a predetermined page feed
3) None of this requires any user interaction or bounces the application to mobile safari, etc.
I dont really understand what you want, but it is possible to authenticate without user interaction:
If the request requires authentication in order to make the
connection, valid credentials must already be available in the
NSURLCredentialStorage, or must be provided as part of the requested
URL. If the credentials are not available or fail to authenticate, the
URL loading system responds by sending the NSURLProtocol subclass
handling the connection a
continueWithoutCredentialForAuthenticationChallenge: message.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html#//apple_ref/doc/uid/TP40009507-SW1
There is a way for authentication:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
Ok - I figured this out. Feel pretty silly that I didn't know you could do this.
You can request an access token for an app id & secret. This will allow you to make public data requests that require an access token.
TO REQUEST ACCESS TOKEN:
https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=11111111&client_secret=9999999999
Then, simply use the returned Access Token in your Feed Request:
https://graph.facebook.com/musicpage/feed?access_token=ACCESS_TOKEN
If this is against TOS or deprecated - please let me know. For now this seems like the solution!
I have a client (on iOS) that connects to a server using a hard-coded https url.
When a connection is established the server may indicate that for future connections a different machine name and/or port should be used. In addition the server can specify url location suffixes to fetch data from.
i.e. the following URL might be hardcoded in the client:
https://machineName.address.port/url-suffix
and after a connection is established the sever could inform it to use machineName2 and portX and url-suffix /someLocation/somewhere, so the next time the client connects it will use the url
https://machineName2.address.portX/someLocation/somewhere.
The address part or the url cannot change.
At the moment the client has the following for the connection authentication challenge, i.e. it'll connect to anything:
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
SecTrustRef trust = challenge.protectionSpace.serverTrust;
NSURLCredential *cred;
cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
}
At the moment this app isn't doing anything that requires heavy security - there's no bank info being accessed, the user doesn't log onto anything, no user info is being transmitted. The client is just downloading data from the server onto the device.
Without adding certificate checking on the client side could a spoof server send porn to the device or something, or is the fact a https connection is made and the url address is hardcoded sufficient?
HTTPS provides data encryption and authentication, but your certificate should be signed by a certificate authority. Accessing a hardcoded URL is not a security flaw—that's how webservices/APIs work. However, without proper certificate setup someone could potentially impersonate your server. Just using SSL/TLS is not enough.