How to combine scribe authorization with gdata services - gdata

Does anyone know how to combine oauth done with scribe with Gdata Service:
So after authenticating with scribe I have access token and need to push it to instance of gdata ContactsService (for any other service it would work the same, i guess).
I've tried simple
GoogleCredential credential = new GoogleCredential();
credential.setAccessToken(accessTokenString);
where accessTokenString is a String achieved from scribe after running
Token accessToken = service.getAccessToken(requestToken, verifier);
but that didn't work with exception on doing request:
Exception in thread "main" java.lang.NullPointerException: No authentication header information
at com.google.gdata.util.AuthenticationException.initFromAuthHeader(AuthenticationException.java:96)
at com.google.gdata.util.AuthenticationException.<init>(AuthenticationException.java:67)
at com.google.gdata.client.http.HttpGDataRequest.handleErrorResponse(HttpGDataRequest.java:608)
at com.google.gdata.client.http.GoogleGDataRequest.handleErrorResponse(GoogleGDataRequest.java:564)
at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:560)
at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:538)
at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:536)
at com.google.gdata.client.Service.getFeed(Service.java:1135)
at com.google.gdata.client.Service.getFeed(Service.java:998)
at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:645)
at com.google.gdata.client.Service.getFeed(Service.java:1017)
It would be nice to combine scribe with gdata, as I have scribe ready, and gdata offers a better api to handle data from google
Thanks

I don't know what accessTokenString is on your example. I assume it's the result of calling the toString method on a Scribes accessToken object.
If that's so and gdata is expecting just the access token, you should do:
Token accessToken = service.getAccessToken(requestToken, verifier);
GoogleCredential credential = new GoogleCredential();
credential.setAccessToken(accessToken.getToken());

Related

Verify facebook token

I have a client application which authenticates with facebook and returns the token successfully. I would like to persist this data to the server without having to pass the entire object. Instead I would like to pass the resulting token from the client side authentication to my C# api in the authorization header and validate this token on the server.
Question, is it possible to verify the token on the server side? How to do it?
I am doing this via google, and need a facebook equivalent:
var googleResult = GoogleJsonWebSignature.ValidateAsync(
accessToken,
new GoogleJsonWebSignature.ValidationSettings
{
Audience = new[] { "secret key here.apps.googleusercontent.com" }
}
).GetAwaiter().GetResult();

403 Forbidden while accessing Leycloak rest API with a valid user credentials

I have set up a Keycloak server and a user named 'sample' is given permissions to access the rest ADMIN APIs, I granted permissions to the relevant realm and client_id. And I'm able to access the rest APIs using the postman service using this user credentials 'sample/sample'.
so through Angular application, I was trying to access the API that fetches the roles in a specific realm. since not all the login user will have the rest admin access, I'm using the user credentials(sample/sample) that have the access to admin API, but when I try to access the API, the APIs are forbidden,
this.getKeycloakAccessToken().subscribe((Tokres:any)=>{
console.log('accessToken: ', Tokres.body.access_token);
if(Tokres && Tokres.status === 200 && Tokres.body.access_token){
this.getKeycloakRoles(Tokres.body.access_token).subscribe((roleRes:any)=>{
console.log(roleRes);
},(roleErr:any)=>{
console.log('error while fetching roles..');
console.log(roleErr);
})
}
},(tokErr:any)=>{
console.log('error while accessing keycloak token...');
console.log(tokErr);
})
getKeycloakAccessToken(){
const url = 'http://keycloak-keycloak.router.default.svc.cluster.local.......nip.io/auth/realms/myRealm/protocol/openid-connect/token';
const authH = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const body = new HttpParams()
.set('username', 'sample')
.set('password', 'sample')
.set('grant_type', 'password').set('client_id','rest-client');
return this.http.post(url, body,{headers:authH,observe:'response'});
}
getKeycloakRoles(access_token){
const url = 'http://keycloak-keycloak.router.default.svc.cluster.local........nip.io/auth/admin/realms/myRealm/roles'
const authH = new HttpHeaders().set('Authorization','Bearer ' + access_token);// ({'Authorization':'Bearer ' + access_token});
return this.http.get(url,{headers:authH,observe:'response'});
}
and when I tried to debug, the access_token shown in console is different from that of request headers
[![network log][2]][2]
After debugging for couple of days, I figured out the reason for the difference in Access token, the API call is being invoked with the access_token of logged in session, though the program has source code written to set the headers set with access token of user 'sample/sample'. is there any way to trigger the API with the given access_token rather with the logged in user's access_token.
This might not be the solution, but just a couple of workarounds that worked for me.
Allow permissions (set 'Relam Management') to all the logged in users from the key cloak admin console, this way irrespective of user, whoever logs in will be able access the rest Admin APIs, follow this below
reference
From keycloak client library, we have a initializeKeycloak() , that has configurations set for the application, so disable the 'enableBearerInterceptor' which will say the application not to use the access_token generated by logged in user to set the headers of each request. this way we can avoid the forbidden error.
But with approach no.2, you can not use the AT of logged in user as we r disabling the enableBearerInterceptor.
And with solution no.1, if you are not having control on who are the users logging in to your application, i,e using some third party tool like LDAP to set the users, then it this won't serve the solution.

Maintain flask_login session in flutter

Soo...I have an app with flask backend and flutter frontend. It utilizes flask_login to manage users. Problem is - I don't know how to maintain session on client side. Flutter client gets response from server, but I don't see any token, or user_id inside.
So far, I've tried to parse responce, with no luck and I've used solution from How do I make an http request using cookies on flutter?
also, without success.
Server-side https://github.com/GreenBlackSky/COIN/blob/master/api_app/app/login_bp.py
Client-side https://github.com/GreenBlackSky/coin_web_client/blob/master/lib/session.dart
Maybe, using flask_login was not such a good idea after all..
Have you tried with the request_loader approach? You can log in from Flutter client using a url argument and the Authorization header. Quoting from the documentation,
For example, to support login from both a url argument and from Basic Auth using the Authorization header:
#login_manager.request_loader
def load_user_from_request(request):
# first, try to login using the api_key url arg
api_key = request.args.get('api_key')
if api_key:
user = User.query.filter_by(api_key=api_key).first()
if user:
return user
# next, try to login using Basic Auth
api_key = request.headers.get('Authorization')
if api_key:
api_key = api_key.replace('Basic ', '', 1)
try:
api_key = base64.b64decode(api_key)
except TypeError:
pass
user = User.query.filter_by(api_key=api_key).first()
if user:
return user
# finally, return None if both methods did not login the user
return None
If you don't want to use flask_login anymore, I would suggest flask_jwt_extended for your case. Note that authentication will be carried out using JWT tokens instead of sessions.
Basically, you would need to create three routes: one for creating access and refresh tokens when the user logged in, one for refreshing the expired access token with the refresh token and one for removing the tokens when the user logged out. Then you would protect your API endpoints with the #jwt_required decorators.
Please refer to the documentation for detailed implementation.

MSAL, Azure MobileService and Auto REST calls get 401 Unauthorized

I have an app (currently in UWP) that makes use of MobileServiceClient and AutoRest to an Azure App Service API App. I successfully used the winfbsdk and can authenticate thru that and then get it to login to MobileService.LoginAsync with the FB access token as a JObject. I also take that JObject and send it in the x-zumo-auth header when making calls to the API App via AutoRest within the app.
What I would like to do is be able to authenticate using MicrosoftAccount. If I use MobileService.LoginAsync, I cannot get the proper token and pass it along to AutoRest - it always comes back as 401 Unauthorized.
I tried to used MSAL, but it returns a Bearer token and passing that along also comes back as 401 Unauthorized.
Is there any good way to do this? I started on the route of MSAL since that would support Windows desktop, UWP and Xamarin Forms which will be ideal. I just need info on how to get the proper token from it to pass along to an AutoRest HttpClient that goes back to the Azure App Service API App.
Update:
If I use the following flow, it works with Facebook, but not with MicrosoftAccount.
-Azure AppService with WebAPI (and swagger for testing via a browser)-Security setup through the Azure Dashboard on the service and configured to allow Facebook or MicrosoftAccount
1. On my UWP app, using winfbsdk, I login with Facebook, then grab the FBSession.AccessTokenData.AccessToken and insert that into a JObject:
JObject token = JObject.FromObject
(new{access_token = fbSession.AccessTokenData.AccessToken});
2. Login to MobileServiceClient
user = await App.MobileService.LoginAsync
(MobileServiceAuthenticationProvider.Facebook, token);
Login to API App with HttpClient and retrieve the token to use in X-ZUMO-AUTH
using (var client = new HttpClient())
{
client.BaseAddress = App.MobileService.MobileAppUri;
var jsonToPost = token;
var contentToPost = new StringContent(
JsonConvert.SerializeObject(jsonToPost),
Encoding.UTF8, "application/json");
var asyncResult = await client.PostAsync(
"/.auth/login/" + provider.ToString(),
contentToPost);
if (asyncResult.Content == null)
{
throw new InvalidOperationException("Result from call was null.");
return false;
}
else
{
if (asyncResult.StatusCode == System.Net.HttpStatusCode.OK)
{
var resultContentAsString = asyncResult.Content.AsString();
var converter = new ExpandoObjectConverter();
dynamic responseContentAsObject = JsonConvert.DeserializeObject<ExpandoObject>(
resultContentAsString, converter);
var applicationToken = responseContentAsObject.authenticationToken;
ApiAppClient.UpdateXZUMOAUTHToken(applicationToken);
}
}
}
ApiAppClient.UpdateXZUMOAUTH call just does the following:
if (this.HttpClient.DefaultRequestHeaders.Contains("x-zumo-auth") == true)
{
this.HttpClient.DefaultRequestHeaders.Remove("x-zumo-auth");
}
this.HttpClient.DefaultRequestHeaders.Add("x-zumo-auth", applicationToken);
Any subsequent calls using the ApiAppClient (created with AutoRest from the swagger json of my Azure AppService WebAPI) contain the x-zumo-auth header and are properly authenticated.
The problem occurs when trying to use MicrosoftAccount. I cannot seem to obtain the proper token to use in x-zumo-auth from either MSAL or LoginWithMicrosoftAsync.
For #1 above, when trying for MicrosoftAccount, I used MSAL as follows:
AuthenticationResult result = await MSAuthentication_AcquireToken();
JObject token = JObject.FromObject(new{access_token = result.Token});
And MSAuthentication_AcquireToken is defined below, using interfaces and classes as suggested in the Azure samples: https://github.com/Azure-Samples/active-directory-xamarin-native-v2
private async Task<AuthenticationResult> MSAuthentication_AcquireToken()
{
IMSAcquireToken at = new MSAcquireToken();
try
{
AuthenticationResult res;
res = await at.AcquireTokenAsync(App.MsalPublicClient, App.Scopes);
return res;
}
}
Update - ok with MobileServiceClient, but still not working with MSAL
I got it working with MobileServiceClient as follows:
1. Use MobileService.LoginAsync
2. Take the returned User.MobileServiceAuthenticationToken
3. Set the X-ZUMO-AUTH header to contain the User.MobileServiceAuthenticationToken
user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);
applicationToken = user.MobileServiceAuthenticationToken;
ApiAppClient.UpdateAppAuthenticationToken(applicationToken);
MSAL still not working!
So the original question still remains, what part of the token returned from MSAL do we need to pass on to X-ZUMO-AUTH or some other header so that calls to the Azure AppService WebAPI app will authenticate?
I have an app (currently in UWP) that makes use of MobileServiceClient and AutoRest to an Azure App Service API App. I successfully used the winfbsdk and can authenticate thru that and then get it to login to MobileService.LoginAsync with the FB access token as a JObject. I also take that JObject and send it in the x-zumo-auth header when making calls to the API App via AutoRest within the app.
According to your description, I assumed that you are using Client-managed authentication. You directly contact the identity provider and then provide the token during the login with your mobile back-end, then you could leverage MobileServiceClient.InvokeApiAsync to call your API APP, which would add the X-ZUMO-AUTH header with the value authenticationToken after you invoke MobileServiceClient.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);
What I would like to do is be able to authenticate using MicrosoftAccount. If I use MobileService.LoginAsync, I cannot get the proper token and pass it along to AutoRest - it always comes back as 401 Unauthorized. I tried to used MSAL, but it returns a Bearer token and passing that along also comes back as 401 Unauthorized. Is there any good way to do this?
AFAIK, for the client-flow authentication patterns (AAD, Facebook, Google), the token parameter for LoginAsync would look like {"access_token":"{the_access_token}"}.
For the client-flow authentication (Microsoft Account), you could leverage MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}"), also you could use LoginAsync with the token parameter of the value {"access_token":"{the_access_token}"} or {"authenticationToken":"{Live-SDK-session-authentication-token}"}. I have tested LoginAsync with the access_token from MSA and retrieve the logged info as follows:
In summary, when you retrieve the authentionToken after you have logged with your mobile back-end, you could add the X-ZUMO-AUTH header to each of your API APP requests with the authentionToken.
For more details, you could refer to this official document about authentication works in App Service.
UPDATE
I have checked this https://github.com/Azure-Samples/active-directory-xamarin-native-v2 and used fiddler to capture the network packages when authenticating the user and get an access token. I found that MSAL is working against Microsoft Graph and REST and when the user is logged, you could only retrieve the access_token and id_token, and both of them could not be used for single sign-on with your mobile back-end.
While the official code sample about Client-managed authentication for Azure Mobile Apps with MSA is using the Live SDK. As the Live SDK REST API mentioned about signing users, you could get an access token and an authentication token which is used for single sign-on scenario. Also, I have checked the Server-managed authentication and found that app service authentication / authorization for MSA also uses the Live SDK REST API.
In summary, you could not use MSAL for client-managed authentication with MSA, for client-managed authentication, you need to leverage Live SDK to retrieve the authentication_token then invoke MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}") to retrieve the authenticationToken from your mobile backend. Or you could just leverage server-managed authentication for MSA. For more details about Live SDK, you could refer to LiveSDK.

Could not authenticate with OAuth

I am using Tweetsharp and I am trying to play with the Twitter Application. At present it is a simple console application.
I have searched in the net and found some articles where most of them are stating that after August 16th 2010, the basic authentication for the twitter is no longer applicable. Instead OAuth has come into place.
Henceforth, I have gone to the Twitter Apps and created one for me.(since it's a desktop application, so I choose Application Type to be Client and not browser.)
These are the various information that I got
Consumer key : NxDgjunKLu65CW38Ea1RT
Consumer secret :JOomsRGPTHct9hFjGQOTpxScZwI5K8zkIpOC1ytfo
Request token URL : https://twitter.com/oauth/request_token
Access token URL : https://twitter.com/oauth/access_token
Authorize URL: https://twitter.com/oauth/authorize
As a very basic step what have planned is that, I will write/post some tweet something to my wall.
Henceforth, I made the following(some code has been taken from web as I was using those as a reference)
string consumerKey = "NxDgjunKLu65CW38Ea1RT";
string consumerSecret = "JOomsRGPTHct9hFjGQOTpxScZwI5K8zkIpOC1ytfo";
FluentTwitter.SetClientInfo(new TwitterClientInfo { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret });
//Gets the token
var RequestToken = FluentTwitter.CreateRequest().Authentication.GetRequestToken().Request().AsToken();
var twitter = FluentTwitter.CreateRequest()
.AuthenticateWith(
consumerKey
,consumerSecret,
RequestToken.Token,
RequestToken.TokenSecret)
.Statuses().Update("I am writing my first tweets").AsXml();
var response = twitter.Request();
var status = response.AsStatus();
But the response is
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<error>Could not authenticate with OAuth.</error>
<request>/1/statuses/update.xml</request>
</hash>
I am trying for a long time to understand the problem but all in vain.
I need help.
Thanks
Getting the request token is only the first step of the OAuth process. You need to get the request token, authorize the token, and then trade if for an access token. You then use the access token to send a tweet.
See this link for a flowchart of the full OAuth process.