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!
Related
I am using the Google-API-Client and the gtm-oauth2 libraries. When the logon successfully completes
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuth2Authentication *)authResult
error:(NSError *)error {
I am handed back an access token in authResult.authResult
However if I look at what is saved to my keychain either automatically or using
[GTMOAuth2ViewControllerTouch saveParamsToKeychainForName:kGoogleKeychainItemName authentication:authResult];
I do not see that the access token is saved once I retrieve it. Only the refresh token is saved
If I immediately or any other time do
GTMOAuth2Authentication *auth =
[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kGoogleKeychainItemName
clientID:kGoogleClientID
clientSecret:kGoogleClientSecret error:&error];
My access Token is nil
I assume that this is deliberate but I cannot see any documentation on this. Why does this happen and what is the thinking behind it.
There are some variants why data is not saving:
Possible the method (authForGoogleFromKeychainForName ) is not supported.
Possible if a scanner of finger print is existed in the phone, there should be additional feature in settings for using Keychain - we have some problems with the saving on the phone5 where fingerprint is existed.
The reason only the Refresh Token is used from the keychain is that this simplifies the OAuth2 process.
We do not have to verify that the Access token is still valid.
It makes the process easier to program and the cost is negligible.
Can anybody help me to know how https request are processing using NSRULConnection? I had gone through lot of tutorials and Apple documentation. But I am not able to understand how it is working. I have implemented the following delegates to process an https request.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
When I implemented the above delegate, I got response from the server successfully. Can anyone help me to know how this is working. Also what are each parameters in the delegate and what it is doing?
Thanks in advance.
Think of the protectionSpace as the server. The delegate method connection: canAuthenticateAgainstProtectionSpace is used to ask you if you can handle the authentication requirements of the server. In your case, you say "if we're talking about the SSL certificate (that's what NSURLAuthenticationMethodServerTrust usually means), yes, I can handle that".
The connection then asks you to do just that with connection:didReceiveAuthenticationChallenge and provide a NSURLCredential for this specific server. With credentialForTrust: you create the credential by using the information stored in your keychain for the certificate of this server. With useCredential:forAuthenticationChallenge: you finally tell the connection to answer the challenge with this credential, i.e. use the keychain data to validate the certificate.
This example will help you How To Use iOS NSURLConnection By Example
I'm using AFNetworking and associated goodies, and I've subclassed AFOAuth2Client to do some OAuth work with tokens and so forth.
For testing purposes, I'm working on a dev server that requires a username & password to access the pages/API endpoints. When I browse to one of the pages, I get a little dialog box, enter the credentials, and I'm good for some time. As I understand it this is "Basic Authentication" or "Basic Access Authentication".
So when I instantiate my AFOAuth2Client subclass, I use
[self setAuthorizationHeaderWithUsername:#"user" password:#"pass"];
with the appropriate username and password that I would type into my browser when prompted, but when I attempt to access the dev server, using the HTTPOperationWithRequest: method, I get rejected.
So instead, when I instantiate the client, I try:
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"user" password:#"pass" persistence:NSURLCredentialPersistenceNone];
[self setDefaultCredential:credential];
And this works fine for all requests I make; the server lets me in.
Now as far as I understand, the first method is setting the Authorization: HTTP header with my credentials, and the second method tells my request that when it gets challenged, set the Authorization: HTTP header with my credentials...same thing, no?
Why would the first method fail and the second one succeed?
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.
OK... so here is my code:
twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];
[twitterEngine setConsumerKey:CONSUMER_KEY secret:CONSUMER_SECRET];
accessToken = [twitterEngine getXAuthAccessTokenForUsername:profile.twitterUserId password:profile.twitterPassword];
NSLog(#"Access token: %#", accessToken);
the console shows the access token returned just fine (so it seems to work)
eg. Access token: C8A24515-0F11-4B5A-8813-XXXXXXXXXXXXXX
but instead of accessTokenReceived method being called next on my delegate, it calls requestFailed with a 401. How can I be getting a 401 unauthorized and getting an access token back from the method call?????
xAuth, the process for exchanging a login and password for an access token, is a privilege for applications that verifiably meet Twitter's criteria: desktop or mobile applications that are otherwise unable to provide the entire three-legged OAuth flow. Out-of-band OAuth and custom URI schemes are still preferred over xAuth.
If you've exhausted other OAuth implementations and want to use xAuth, you can contact Twitter through api#twitter.com from an email address directly associated with the account owning the application. Include full details about your application, its user base, links to screenshots of it in action, and a detailed description on why this form of authorization is appropriate for your application. Inquires for xAuth are considered on a case-by-case basis and will not be granted to all applicants.
Implementors of xAuth must not store logins and passwords within their applications -- this is not a drop-in replacement for basic auth or a way to avoid implementing OAuth authentication.
Found the issue... for anyone else that has this problem... Getting your app approved for OAuth is only part of the process. Although it looks like you are done and the twitter page gives you your key and secret... there is one not-quite-so-easy-to-find next step. You must send an email to api#twitter.com and ask them to actually enable it.
That was fun figuring out. :)