I am using xmpp framework to integrate gtalk in my application. I have successfully authenticated user using OAuth 2.0. Now i want to use the access token and user email to authenticate xmpp stream. I know that the authentication call get sent xmppStreamDidConnect method using this method authenticateWithPassword. This requires a password, i want to get it done using the google access token. Any help?
Yes you can do it please follow the steps:
Register your app on google developer console.
Generate access token with following scope:
https://www.googleapis.com/auth/googletalk
start authentication as following:
(BOOL)start:(NSError **)errPtr
{
XMPPLogTrace();
// From RFC 4616 - PLAIN SASL Mechanism:
// [authzid] UTF8NUL authcid UTF8NUL passwd
//
// authzid: authorization identity
// authcid: authentication identity (username)
// passwd : password for authcid
NSString *accessToken = #"ACCESS-TOKEN-STRING-FROM Google";//TODO: assign your generated access token
NSLog(#"stream supports: %#",xmppStream.supportedAuthenticationMechanisms);
NSString *payload = [NSString stringWithFormat:#"\0%#\0%#", xmppStream.hostName, accessToken];
NSLog(#"payload = %#",payload);
NSString *base64 = [[payload dataUsingEncoding:NSUTF8StringEncoding] xmpp_base64Encoded];
NSXMLElement *auth = [NSXMLElement elementWithName:#"auth" xmlns:#"urn:ietf:params:xml:ns:xmpp-sasl"];
[auth addAttributeWithName:#"mechanism" stringValue:#"X-OAUTH2"];
[auth addAttributeWithName:#"auth:service" stringValue:#"oauth2"];
[auth addAttributeWithName:#"xmlns:auth" stringValue:#"https://www.google.com/talk/protocol/auth"];
[auth setStringValue:base64];
[xmppStream sendAuthElement:auth];
return YES;
}
Everything should work as expected, please comment.
Related
I'm building an oauth2 client with Flask and Authlib. My code to register the oauth is:
google = oauth.register(
name='google',
client_id='',
client_secret="",
access_token_url="https://accounts.google.com/o/oauth2/token",
access_token_params=None,
authorize_url="https://accounts.google.com/o/oauth2/auth",
authorize_params=None,
api_base_url="https://www.googleapis.com/oauth2/v1/",
client_kwargs={'scope': 'openid email'},
server_metadata_url="https://accounts.google.com/.well-known/openid-configuration",
)
And my /authorize endpoint looks like this:
#app.route('/authorize')
def authorize():
google = oauth.create_client('google')
token = google.authorize_access_token()
resp = google.get('userinfo')
resp.raise_for_status()
userinfo = resp.json()
return str(userinfo)
But I am getting the error
authlib.jose.errors.InvalidClaimError: invalid_claim: Invalid claim "iss"
I had this issue and removing the openid value from scope fixed it. I guess my google config didn't accomodate it,
I have simple app that is trying to do a http web request to a server that requires SAML authentication. Authenticated users will get a http response header with a special token, which is what I need to ultimately get.
My app is .net based and does a pretty simple http web request. It does the request then parses the response header. I later traverse the header for the specific token I need:
...
try
{
WindowsIdentity identity = HttpContext.User.Identity as WindowsIdentity;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.UseDefaultCredentials = true;
req.AllowAutoRedirect = true;
req.Timeout = 30000;
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
if (response == null)
{
throw new Exception("No HTTP Response");
}
StringBuilder sb = new StringBuilder();
Byte[] buffer = new byte[8192];
Stream rStream = response.GetResponseStream();
int count = 1;
do
{
count = rStream.Read(buffer, 0, buffer.Length);
if (count != 0)
{
sb.Append(Encoding.UTF8.GetString(buffer, 0, count));
}
} while (count > 0);
...
The problem is that the server I'm requesting requires SAML authentication. It redirects to an ADFS server upon request. My app server currently uses kerberos authentication but I can enable it to do SAML as well. Both servers use the same IdP (ADFS) and are in the same enterprise.
My question is - since my app can also do SAML on the same IdP, is there anyway I could get the necessary claims to connect directly into the destination server?
How can pass username password as attributes in SAML Request as shown in the code below. I'm using lastpass-saml-sdk.jar to communicate with the GLUU IDP server.
SAMLInit.initialize();
String dir = Constants.METADATA_LOCATION;
if (dir == null)
throw new SAMLException("Unable to locate SAML metadata");
IdPConfig idpConfig = new IdPConfig(new File(dir + "\\gluu-idp-metadata.xml"));
SPConfig spConfig = new SPConfig(new File(dir + "\\sp-meta.xml"));
SAMLClient client= new SAMLClient(spConfig, idpConfig);
// when a login link is clicked, create auth request and
// redirect to the IdP
String requestId = SAMLUtils.generateRequestId();
String authrequest = client.generateAuthnRequest(requestId);
String url = client.getIdPConfig().getLoginUrl() +
"?SAMLRequest=" + URLEncoder.encode(authrequest, "UTF-8");
// redirect to url...
response.sendRedirect(url);
You do not pass username and passord directly to the Identity Provider. After you have redirected the user, the user himself will enter username and password at the IDP.
Here is one of my blog posts describing the flow in SAML Web rowser profile.
I am currently updating my app to .json from xml for Twitters new API v1.1. I currently have .json working and can log on, get me timelines, mentions, but when trying to get direct messages, lists, or user info it seems its looking for "cookies" but it is not stored.
This is the error message received by twitter when trying to make a simple GET user/show call:
Twitter request failed: 08AD12D3-0044-49AB-8D3D-4E61D8398550 with error:Error Domain=HTTP
Code=400 "The operation couldn’t be completed. (HTTP error 400.)" UserInfo=0xce90540
{response=<NSHTTPURLResponse: 0xce94bd0> { URL:
https://api.twitter.com/1.1/users/show.json?screen_name=FreeAppl3 } { status code: 400,
headers {
"Content-Encoding" = gzip;
"Content-Type" = "application/json; charset=utf-8";
Date = "Fri, 14 Jun 2013 09:25:40 UTC";
Server = tfe;
"Set-Cookie" = "guest_id=v1%3A137120194019582695; Domain=.twitter.com; Path=/;
Expires=Sun, 14-Jun-2015 09:25:40 UTC";
"Strict-Transport-Security" = "max-age=631138519";
"Transfer-Encoding" = Identity;
} }, body={"errors":[{"message":"Bad Authentication data","code":215}]}hjD4nzoeOUaTQ1Q%3D}
When I call [twitterEngine isAuthorized]; is returns YES and if I check for my access token string, I receive what was stored on initial login. I have searched and searched as to what is happening or how to fix the issues, but am simply stuck and any help would be greatly appreciated.
Twitter API - https://dev.twitter.com/docs/api/1.1/get/users/show
Twitter Error Codes - https://dev.twitter.com/docs/error-codes-responses
refer FHSTwitterEngine you can use newly FHSTwitterEngine and if you request this method without autenticating, the users status is removed... you need to send consumer key and token along with screen_name..
In FHSTwitterEngine
//get username pass to method. In Dictionary you can get all info
NSString *username = [[FHSTwitterEngine sharedEngine]loggedInUsername];
NSDictionary *data=[[FHSTwitterEngine sharedEngine]getUserProfile:username];
// method to get all user info
-(id)getUserProfile:(NSString *)username
{
if (username.length == 0) {
return getBadRequestError();
}
NSURL *baseURL = [NSURL URLWithString:url_users_show];
OAMutableURLRequest *request = [OAMutableURLRequest requestWithURL:baseURL consumer:self.consumer token:self.accessToken];
OARequestParameter *usernameP = [OARequestParameter requestParameterWithName:#"screen_name" value:username];
NSArray *params = [NSArray arrayWithObjects:usernameP, nil];
id userShowReturn = [self sendGETRequest:request withParameters:params];
return userShowReturn;
}
I am using following code
- (void)linkedInEngineAccessToken:(RDLinkedInEngine *)engine setAccessToken:(OAToken *)token {
if( token ) {
[token rd_storeInUserDefaultsWithServiceProviderName:#"LinkedIn" prefix:#"My app name"];
}
else {
[OAToken rd_clearUserDefaultsUsingServiceProviderName:#"LinkedIn" prefix:#"My App name"];
}
}
- (OAToken *)linkedInEngineAccessToken:(RDLinkedInEngine *)engine {
return [OAToken rd_tokenWithUserDefaultsUsingServiceProviderName:#"LinkedIn" prefix:#"My app name"];
}
- (void)linkedInEngine:(RDLinkedInEngine *)engine requestSucceeded:(RDLinkedInConnectionID *)identifier withResults:(id)results {
NSLog(#"++ LinkedIn engine reports success for connection %#\n%#", identifier, results);
if( identifier == self.fetchConnection ) {
// NSDictionary* profile = results;
}
}
- (void)linkedInEngine:(RDLinkedInEngine *)engine requestFailed:(RDLinkedInConnectionID *)identifier withError:(NSError *)error {
NSLog(#"++ LinkedIn engine reports failure for connection %#\n%#", identifier, [error localizedDescription]);
}
- (void)fetchProfile {
self.fetchConnection = [self.engine profileForCurrentUser];
[self.engine updateStatus:#"Download app from the #Apple #AppStore and #Android #GooglePlay market."];
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark - RDLinkedInAuthorizationControllerDelegate
- (void)linkedInAuthorizationControllerSucceeded:(RDLinkedInAuthorizationController *)controller {
[self fetchProfile];
}
- (void)linkedInAuthorizationControllerFailed:(RDLinkedInAuthorizationController *)controller {
}
- (void)linkedInAuthorizationControllerCanceled:(RDLinkedInAuthorizationController *)controller {
}
#end
I have set up things correctly. It takes me to linkedIn login page and after login to give permissions I get this error
Failed to load page Error Domain=NSURLErrorDomain Code=-1003 "A
server with the specified hostname could not be found."
UserInfo=0x81e2250
{NSErrorFailingURLStringKey=http://www.devbee.ca/?oauth_token=MY_TOKEN&oauth_verifier=VERIFIER,
NSErrorFailingURLKey=MY_REDIRECT_URL/?oauth_token=MY_OAUTH_TOKEN&oauth_verifier=MY_VERIFIER,
NSLocalizedDescription=A server with the specified hostname could not
be found., NSUnderlyingError=0x810ddc0 "A server with the specified
hostname could not be found."}
What is wrong?
Is it because of
- (OAToken *)linkedInEngineAccessToken:(RDLinkedInEngine *)engine {
return [OAToken rd_tokenWithUserDefaultsUsingServiceProviderName:#"LinkedIn" prefix:#"My app name"];
}
The problem is coming from the fact that http://www.devbee.ca is not up and running. I don't know what point in your code or configuration you are referring to http://www.devbee.ca, but that's where there error lies.
I am guessing that in the configuration for your LinkedIn App, you have set the OAuth Accept Redirect URL to http://www.devbee.ca, which is a non-existant URL. But that's just a guess, you need to dig around to figure out why LinkedIn is redirecting you to http://www.devbee.ca.
Update
It seems that you need to set this OAuth Accept Redirect URL to http://linkedin_oauth/success in your app's configuration. It states this in the How To on the GitHub project:
Most importantly, the OAuth Redirect URL must be set to:
http://linkedin_oauth/success for the web view's delegate to be
notified
Due to URL connection error it is a problem with your redirect url.
Look, the error says: "A server with the specified hostname could not be found". That means that you haven't got internet connection or your server hostname is not found in DNS list of your provider or your server url is wrong.
What you could try. The error specifies the error url: "NSErrorFailingURLKey=MY_REDIRECT_URL/?oauth_token=MY_OAUTH_TOKEN&oauth_verifier=MY_VERIFIER". You could try to open in Safari/Chrome/etc on your Mac the specified url "MY_REDIRECT_URL/?oauth_token=MY_OAUTH_TOKEN&oauth_verifier=MY_VERIFIER" and look what will happen. If you see the same error that you should double check your redirect URL. If it successfully is opened that there is a problem with iOS app.