I'm working in order to leverage the usage of the AD for authentication and authorization of several applications, and I'm currently studying how to implement said process.
This is for a Web-Browser to Web-Application flow.
I create an AuthenticationContext instance and use it to sign in, and that much functions normally.
(Code organization simplified for demo purposes)
this.adal = new AuthenticationContext({
tenant: this.tenantId,
clientId: this.clientId,
redirectUri: this.redirectUri,
callback: this.loginCallback,
popUp: true
});
this.adal.login();
It is when I try to acquire a Token that the behaviour becomes fishy.
It is relevant to say that this application's registry in the AD has the permission "Sign in and read user profile" on Microsoft Graph API.
this.adal.acquireToken("https://graph.microsoft.com", function(error, token) {
console.log(error);
console.log(token);
});
The error is written to the console as follows: "Token renewal operation failed due to timeout"; whilest token is written as a null object. A brief look at the "Network" tab while inspecting the page with Chrome reveals such a resource:
authorize?response_type=token&client_id=xxxxx&resource=xxxxx&redirect_uri=http://localhost:8080(.....)
The Status for said resource is 302.
Got any clues? Thanks!
Ok.. it seems like I've figured it out, with a little help from this article click for article and this click for very cool info
I've replaced the following bit of code, in the login callback
this.adal.acquireToken("https://graph.microsoft.com", function(error, token) {
console.log(error);
console.log(token);
});
for this:
var cachedToken = this.adal.getCachedToken(client_id_goes_here);
if (cachedToken) {
this.adal.acquireToken("https://graph.microsoft.com", function(error, token) {
console.log(error);
console.log(token);
});
}
And finally just add this line of code to a function that is run after the acquireToken method redirects to the page:
this.adal.handleWindowCallback();
Hope this is helpful for others who run by this issue!
Related
I'm working on a react-native app with spotify integration. I've set up the oAuth flow w/ auth code grant where I can get the authorization code. I've then set up cloud function on firebase to proxy the actual token exchange (I don't want to reveal my secret to the client!). I've added logs and can see that the function is correctly completing the exchange with the spotify token endpoint, and receiving a refresh and access token.
const tokenRequeset = functions.https.onCall(async (data, context) => {
// spotify network request, error handling, etc here ....
// I want to emphasize that this network request completes
// properly - my log statement below verifies in server logs
// that I'm getting the expected value.
const resp = await axios.post(
"https://accounts.spotify.com/api/token",
QueryString.stringify({
grant_type: "authorization_code",
code: code,
redirect_uri: redirectURI,
}),
{
headers: {
"Authorization": `Basic ${BEARER_TOKEN}`,
"Content-Type": "application/x-www-form-urlencoded",
},
}
);
console.log(resp.data.access_token);
return { status: "success", token: resp.data.access_token };
});
export default tokenRequest
resp.data.access_token is the JWT access token used to hit the spotify API - it's a string value according to the API. (I'd provide an example one, but it is an auth token)
However, when I try to use the firebase/functions package to call my function from my app, I will sometimes get a 'FirebaseError: Response is not valid JSON object.'
What makes this extra fun is that it's inconsistent - yesterday I had the issue, and then it went away (without changing my code!). I was able to hit both the local emulator function and then the deployed function no problem, but today the 'FirebaseError: Response is not valid JSON object.' error is back.
I have checked the logs for the failed invocations both locally and on the deployed function, and in both cases the spotify API call is working - I'm getting all the expected behavior right up until the return (which isn't working for some reason).
On the client side, I'm configuring firebase like so:
const firebaseConfig = {
// Shhhhhh
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const functions = getFunctions(app);
// Uncomment to run locally
connectFunctionsEmulator(functions, "localhost", 5001);
export { app, functions };
And then exposing and calling it like so:
const SpotifyAuth = httpsCallable(functions, "spotify-auth");
const resp = await SpotifyAuth(code, redirectURI)
(I know this isn't full code - I grabbed the relevant portions. Happy to provide more if needed).
I tried looking up this error, and I found results from ~2018/2020 with the old style of firebase/functions, but they seem to be related to region and I'm deployed in the default us-central1 - according to the SDK documentation that means I shouldn't touch it.
The existing solutions to the problem also seem to be based on the old style of function calls, rather than the more recent httpsCallable() and getFunctions(app).
I'm going insane trying to figure out why sometimes I'm getting this error
EDIT:
More information on the error - I ran my code again today and didn't see the error locally, but I DID see it when I hit the deployed function.
Again, I want to emphasize that I think the error is in the firebase network response - if you look at the network request I receive a 200 but the response is empty.
Did an additional full mockup of a function to see what would happen:
const test = functions.https.onCall((data, context) => {
console.log("function call");
return { status: "success", token: "asdfasdfasdfasdfasfs" };
});
export default test;
I'm getting the same error.
UPDATE:
I've given up on using the sdk and onCall method for firebase cloud functions - all of my testing thus far indicates that this is a bug or error on the google cloud function side, and there's nothing I can do from my side.
The good news is the onRequest approach seems to not have this issue - it's behaving properly and reliably.
I really hope that I've messed up along the way and there's a solution I've missed - the SDK seems fantastic and I like the integration it (is supposed to) offer, but as far as I'm aware right now unless there's a bug fix (or update to the documentation if I'm doing something wrong) it seems like it simply won't work.
I'm still planning on using firebase, but from my experience thus far I'd advise anyone early in their server work to consider using another offering (at least if you need to use the functions - I was able to get storage working).
I have code like this:
var auth = firebase.auth()
var provider = new firebase.auth.TwitterAuthProvider();
auth.signInWithPopup(provider).then(function(result) {
if (result) {
var user = result.user;
//init(user);
}
}).catch(function(error) {
term.error(error.message).resume();
term.error('try again');
});
and I've just get error but I've got this as error:
{"error":{"errors":[{"domain":"global","reason":"invalid","message":"Malformed response cannot be parsed"}],"code":400,"message":"Malformed response cannot be parsed"}}
try again
Does it mean that to get the message I need to call:
error.message.message
and error object is error.message.error?
Or is the error.message string of a json from twitter?
I can't find this information in documentation and I can't look at developer tools because when I've run the code again I didn't get the same error, it was some temporary glitch.
I had this same issue using Twitter Oauth, namely Malformed response cannot be parsed message.
The fix was for me to sign out of my Twitter account that has the oauth app then sign back in. That seems to be the fix for me.
I am having problems getting MSAL(x) working - The login popup succeeds, but when I try to retrieve and access token from the id token using acquireTokenSilent, it causes the app to reload (all resources, per dev tools network tab), and throws an error 'Token renewal operation failed due to timeout: null'. I've searched for relevant SO questions / google, but have had no luck finding similar issues. The crazy thing is, it WORKED the other day and just stopped - even reverting to the same code does not resolve the issue.
Using acquireTokenPopup in the silent's error handler displays a popup, but won't allow login with the same user ('We don't recognize this domain name') but shows the correct MS App name. This is driving me crazy.
Relevant code (in a React component click handler):
onMSLogin() {
const { msLoginFailure } = this.props;
const userAgentApplication = this.userAgentApplication;
userAgentApplication.loginPopup(['user.read'])
.then(function () {
console.log('User login success');
const scopes = ['User.Read'];
userAgentApplication.acquireTokenSilent(scopes).then((accessToken) => {
console.log('Access token acquired (silent): ', accessToken);
this.getGraphData(accessToken);
}, (error) => {
console.error('Silent token fail: ', error);
userAgentApplication.acquireTokenPopup(scopes).then((accessToken) => {
console.log('Access token acquired (popup): ', accessToken);
});
})
}, function (error) {
// handle error
console.log('MS Login Failure: ', error);
if (msLoginFailure) msLoginFailure(error);
});
}
I believe your issue is related to MSAL.js Issue #106, and is patched within the 'dev' branch. I've been working with Microsoft the past few weeks on this library, and I've been told that an official release is due to be cut this week.
I have a backend API written in Ruby and a client App that uses Angular. I'd like to authenticate the user to authenticate the user via the Angular app.
As such I've created my App on Asana. I'm having a few issues though:
First issue: I'm using the Authorisation Endpoint of Authorisation Code Grant. After reading the docs, I realised that I have to use Implicit Grant instead, which is more suitable for a browser-based app, however when I change it to Implicit Grant, save it and reload the page, it changes back to Authorisation Code Grant.
Then on my Angular App I have the following code:
var client = Asana.Client.create({
clientId: 133,
clientSecret: 'mysecretcode',
redirectUri: 'http://localhost:7699/profile'
});
client.useOauth({
flowType: Asana.auth.PopFlow
});
client.authorize().then(function () {
console.log('Auth completed');
}).catch(function (err) {
console.log(err);
});
client.users.me().then(function (result) {
console.log(result);
});
The above almost works. I do get redirected to Asana for the authorisation part, once I click on "Allow", I'm redirected back to my app, and I do get a code as part of the url. The code is something like:
http://localhost:7699/profile#access_token=very_long_string
If I understood the docs correctly, I could use the above access_token to make my first request. When I tried using Asana's JS library to make a request like so:
client.users.me().then(function (result) {
console.log(result);
});
Please note the client object I'm referring to is the same I've created earlier for authorisation. The above returns a 401, Unauthorised code.
Then I tried the following:
var params = {
grant_type: 'refresh_token',
client_id: 876787,
client_secret: 'some_secret',
redirect_uri: 'http://localhost:7699/profile',
code: my_access_code
};
$http.post('https://app.asana.com/-/oauth_token', params).then(function (result) {
console.log(result);
});
Which also gets me a 401 unauthorised code.
What am I doing wrong here?
I recommend you start by copy-pasting one of the examples from the node-asana examples directory into your app, and seeing if that works.
If you want to keep using the popup flow, the thing I suspect you are missing is the call to Asana.auth.PopupFlow.runReceiver(); in popup_receiver.html. This should be on the page pointed to by your redirect_uri, and tells the page that created the popup the auth data it needs to make subsequent requests. Also note how the page that originates the authentication request (popup.html) includes actions that happen after authentication in the callback passed to then: this ensures that these actions happen only after the user completes authentication through the popup.
I'm using https://oauth.io/ service and I'm a little bit unlucky with finding correct documentation on few things:
Is it possible to unauthorize one or another social network from application? In other words destroy permissions for application to use user's settings of that network.
How do I make google plus oauth work:
There is an example for facebook:
OAuth.popup('facebook', function(err, res) {
if (err) {
// do something with error
}
res.get('/me')
.done(function(data) {
alert('Hello ' + data.name)
})
})
It does work for me but I can't figure out how can I make it work with google+ API. When I change provider to google_plus I manage to get authorization token but I'm not sure how to proceed further because calling res.get('/me') doesn't work ('I suppose /me is only for facebook API'). I've tried lots of different other urls that are for google+ but it seems that because G+ doesn't support CORS request it makes request to local oauthd server like so: options.url = config.oauthd_url + '/request/' + options.oauthio.provider + options.url; network returns that no such endpoint exists.
Please if anyone know how to solve this help me.
Thank you
I just ran into this problem too, and I found a jsfiddle
res.get('/plus/v1/people/me').done(function (me) {
$('#connect').slideUp('fast')
$('#res').html(template({
data: me
})).slideDown('fast')
res.get('/plus/v1/people/me/activities/public').done(function(activities) {
$('#activities').html(activitiesTemplate({
data: activities
}))
});
})