For the past few years I have been using an unattended remote server to process invoices through the XERO API (Oauth 1.0)
Periodically (every financial year) we create a new XERO organisation to keep things tidy and avoid slow down.
I have just come to create a new organisation and associated app but have found that I can only use Oauth 2.0, which I do not have a massive issue with, BUT the fact I have to 'user' authenticate is going to be a real problem as my process is 'unattended' and started via CRON jobs.
Can anyone tell me if there is a way around this? and if not are there any solutions to do this?
Alternatively is there any way I can change one of my existing Oauth 1.0 apps to point to a different organisation (i.e. the new one I have just created)?
It seems a little short sighted not to have considered unattended processes, I cannot be the only person doing this??
Any help or pointers would be greatly appreciated.
Thanks,
Mike.
Yes you are not the only one doing this :) & yes, private apps are essentially deprecated end of 2020 - the move was not taken lightly. Since every API action through Xero's api is on behalf of a user account the team decided to move towards OAuth2.0 (Industry Standard) with a user consent screen.
If you need these long standing api connections on behalf of a user - they will need to initially authenticate that API connection at least a single time to get you an access_token and `refresh_tokenà . Access tokens are valid for 30 minutes, while the refresh token is good for 60 days.. So as long as you refresh > 2 months you can persist that longtail process.
If you don't have the means to build out that initial authentication screen to have your user validate on their own, you can use this CLI tool to get your initial token set to securely store in your remote server. An additional change is that that (or some) process will need to ensure the token is refreshed before use, and has given permissions to connect to a specific user's tenant-id as they might be a part of multiple Xero orgs & that manual consent screen is where a user selects which tenant/org they are giving API permissions to.
CLI to get Xero tokens from the command line
https://github.com/XeroAPI/xoauth
More info here: https://community.xero.com/developer/discussion/109207632#answer110970761
UPDATE
client_credentials aka machine to machine are coming to Xero's OAuth2.0 gateway.
You can read more about it here:
https://developer.xero.com/announcements/custom-integrations-are-coming/
Related
We use XERO to authenticate and sign in to our app on firebase, however, we dont want a user to connect with multiple organisations, we just want a user to sign in and choose a single organisation.
If we remove all tenant connections from our app once a user have finished signing in, this will solve our problem, and we already do this upon logout for the same reason.
I just wanted to find out, is there any implications of doing this ? Will our logged in user still be able to make api calls and get new access tokens ?
I could not find any info of this in the XERO docs.
Thanks
The list of connected tenants represents the orgs the user has authorized your app to interact with their Xero data on their behalf. Deleting the connections by making a DELETE call to the connections endpoint with a specified connection ID will effectively un-authorize your app to interact with that orgs Xero data until the user reauthorizes your app to do so.
So, the shorter answer is - no, you won't be able to make api calls after disconnecting.
What I think you are after is limiting the XeroAPI access_token to only be able to write to a single org at a time. This can be achieved through your UX by simply deleting all connections if they try to go through your authorize flow a second time.
That way you are limiting their API connection to a single org, and if they want to change the org they are connecting to they can use your UI to disconnect/reconnect to another one.
XeroAPI Documentation
https://developer.xero.com/documentation/oauth2/auth-flow
Removing connections
If you would like to remove an individual tenant connection from your app (e.g. a user wants to disconnect one of their orgs) you can make a DELETE request on the Connections endpoint:
DELETE https://api.xero.com/connections/{connectionId}
We are using azure ad for authentication for our application and dealing with token expiration of Azure Ad.
We need to fetch the list of users who are currently working (logged in ) into the application.
And the list of users signed out(logged off) from the application.
Its like to track the online and offline users on our application.
which Microsoft graph API we need to use . I went thru the Microsoft documentation but couldn't find the API for this use case.
Please share some code or the way I can achieve without storing user session in my db.
I'm sorry to tell you there is no such graph api command as far as I'm aware. like you said the only way to reliably do it is storing user session information on your own.
the only other thing that I can think of that you could do is try to extrapolate login information from azure audit logs, get get an approximation. you can get a list of sign-ins as per this graph endpoint. https://learn.microsoft.com/en-us/graph/api/signin-list?view=graph-rest-1.0&tabs=http
There is also the endpoint auditLogs/directoryAudits as per here https://learn.microsoft.com/en-us/azure/active-directory-b2c/view-audit-logs
that may show some information about the id tokens being issued.
other than those 2 options, I don't believe there is any better way at the moment.
After discussion with Microsoft team, We get the input that they don't have any graph api to fetch the active /logged in user list on hosted application.
But we can trace the audit logs api which will help us to get the list of users logged in at certain time. But that list is also not a real time it may have delay of 5 to 10 minutes.
We are going with manually handle the user session details.
pasting below audit log api for reference :
https://learn.microsoft.com/en-us/graph/api/signin-list?view=graph-rest-1.0&tabs=http
https://learn.microsoft.com/en-us/graph/api/signin-get?view=graph-rest-1.0&tabs=http
I am very new to MS Graph and Office 365 and have made good progress. I am an O365 Global Admin for my organisation (a school) and have app development experience. There is a lot of scope for using MS-Access databases in our context for "globally" managing the O365 content. eg contacts, distribution lists and planner tasks. We want to manage these from an on-premises ms-access database or two and with an admin person authenticating the ms-graph activity, ideally.
So, to test, I created a new db and have managed to get it to consume the following endpoint using VBA but with no user authentication for now.
https://graph.microsoft.com/v1.0/groups
However, when I try
https://graph.microsoft.com/v1.0/planner/plans/with my plan id here
I get 401 - Unauthorized: Access is denied due to invalid credentials.
So, clearly my Application registration is wrong or my authentication or both! I have spent hours searching for examples and help and because of the evolving nature of the ecosystem I am finding it pretty hard to work out what I should do now (as opposed to a year or two ago).
The authorisation that generates the access_token that works to allow me access to the groups is:
POST
https://login.microsoftonline.com/{my tenant id here}/oauth2/token
grant_type=client_credentials
client_id={my client id}
client_secret={my url encoded secret} resource=https://graph.microsoft.com
but using that same access_token for the planner tasks throws the 401 error.
My app permissions look like this:
I presume this is because of the difference between the Application and Delegated types but have not fully grasped it all yet. And, I suspect I am using the wrong authentication flow anyway. :-(
So, my questions are:
1. Do my permissions look right?
2. Is my authentication flow correct? Should I be using these instead? ie have I been working from old information?
https://login.microsoftonline.com/{my tenant id here}/oauth2/v2.0/authorize
https://login.microsoftonline.com/{my tenant id here}/oauth2/v2.0/token
As you can tell I have become somewhat confused. If anyone can point me in the right overall direction given what I am attempting that would be so helpful.
Thanks so much,
Murray
1. Do my permissions look right?
Yeah undoubtedly, your azure portal permission seems alright. You need dedicated permission for that also need to grant admin consent which you have done perfectly shown on screen shot.
2. Is my authentication flow correct?
As you are using Client Credentials Grant Flow request format seems alright. But I doubt this flow is suitable for the API you are trying to call. because this API requires dedicated permission.
3. Should I be using these instead?
Since this API need dedicated permission you could use authorization code grant flow.
Follow below steps to get your token using Authorization Code grant flow
Get Authorization Code:
https://login.microsoftonline.com/YourTenant.onmicrosoft.com/oauth2/v2.0/authorize?client_id={ClientId}&response_type=code&redirect_uri={redirectURI}&response_mode=query&scope=https://graph.microsoft.com/.default
Request Token oauth2/V2.0/token with your code:
Request URL: https://login.microsoftonline.com/common/oauth2/V2.0/token Or https://login.microsoftonline.com/YourTenant.onmicrosoft.com/oauth2/V2.0/token
Method: POST
Request Body Format
client_id:Your_Clinet_Id
scope:https://graph.microsoft.com/.default
redirect_uri:Your_Portal_Redirect_URI
grant_type:authorization_code
client_secret:Your_Client_Secret
code: Paste Code Here
Decode Token:
You could decode your token on https://jwt.io/ and make sure you have required permission on your azure portal.
4. Have I been working from old information?
No, Information has no issue so far I have gone through.
Note: For for details implementation of Authorization Code grant flow you could take a look official docs
We have a large high traffic site with a lot of data on it (similar to Kickstarter), and we want to provide to our content/project creators a means of pulling their data from our site via an API.
Someone suggested I use OAuth, however my experience with OAuth is limited to setting up a twitter datasource.
What I want to do
Provide a user an Application ID and a 'secret'
Allow this user to connect to our application via an api endpoint, authorizing themselves using the api ID and secret
Once verified, allow this user to pull only their data from the application
The data that a user can pull: votes they have cast, pledges they have made, purchases they have made, projects/ideas they have launched, data about those projects/ideas (votes/purchases/orders/cancellations etc)
My question is:
Is OAuth overkill?
Is there a better way to handle a user/users website to connect to our API and pull/verify certain data by using the API we make available, while requiring each incoming request to be authorized for the user/site initiating that request.
Ideally, we will have an endpoint that is accessed as:
https://api.oursite.com/request/params
We want this to be as simple as possible for our users that wish to implement this interface. Thanks for your help!
Generally it's OAuth, in combination with SSL. That's the standard and is likely to stay. Before we saw also logins: username + password to access an API but that's becoming less and less.
So the suggested way is OAuth. There are no serious other solutions yet. To make it easier to adopt your API you could release some classes in some development languages so developers can have a quick start. You could start releasing those classes at for example GitHub to raise adoption of your API and get a quick access to developers. They might, if you do well, even start improving it.
Does anyone have clues about how to do this? I'm basically trying to replace the strategy for "Connect With Google" from OpenID to OAuth. The challenge is identifying an old user (user on Google open ID) when a user signs in under the new OAuth scheme.
I have a working implementation which relies on email address as the primary key, as the open ID strategy captures that. The problem is, I don't want to ask for email in the OAuth flow. The ideal value is simply Google user ID, but the Open ID strategy doesn't seem to capture that.
So I have open ID tokens like https://www.google.com/accounts/o8/id?id=AfSCwGQ4PUaidXSQddJugXKLqU5V0MrXFhJM6UHybPw and trying to understand if I could get a Google ID from that.
UPDATE: I explained here how I ended up doing this migration - http://softwareas.com/migrating-user-accounts-from-google-openid-to-google-oauth-to-google-plus
We don't have a strategy ready today that avoids the user seeing another approval page.
However, rather than attempt to do an OAuth1 based hybrid flow and have to add all that legacy code to your server, I'd suggest you simply correlate on email address and move to OAuth2 login. I'm assuming you're like the majority of sites that end up asking for email address because they usually want it for account recovery. Just make sure you get the email address from OpenId as one of the signed parameters.
Then use the userinfo.email scope and OAuth2 https://developers.google.com/accounts/docs/OAuth2Login and you should be able to migrate with less developer pain.
In addition, we're in the process of adding support for OpenIDConnect and it supports a parameter of login_hint so you'd add &login_hint=bob#gmail.com to your authorization URL and it will steer the approval to the right account. This is not documented right now but it may be useful for you to try it. The user's browser could be logged into Google with a number of accounts and you want to try to get the right one. Always check the email you get from the OAuth2 flow to make sure it matches since this is just a 'hint'.
Users will still have to re-authorize for OAuth2, but we have plans to skip this reauthorization in the future. The main point is to plan on using OAuth2 and we hope to deliver a seamless migration soon and you'll be on a supported protocol.
Google uses directed identifiers for OpenID that are unique per relying party and are explicitly designed to conceal any correlatable identifier for the user. So the short answer is, no there's no way to get a Google ID that corresponds with a given Google OpenID.
One option, however, might be to use Google's OpenID+OAuth Hybrid flow. This allows you to get an OAuth token as part of a normal OpenID flow, which could then be used to get the user's ID from the OAuth2 Login API, which you can then associate with their existing account. Once you've done that for all of your existing users, then switch to using the OAuth2 Login directly.
The trick, of course, with this approach is getting all of your users to login again so that you can send them through the new flow. That will come down to how long you're willing to wait to migrate accounts, and whether you're willing to prod existing users by emailing them and asking them to login again (similar to a forced password reset).