API call switching to Oauth 2.0 with openid - python

I used to query my financial data through Power Query in Power BI. Recently I've switched to doing it through a python script running on Google Cloud functions, triggered by Cloud Scheduler. (is this the best way?) It saves a csv file to GCStorage.
The party that provides the data I'm after is switching to oAuth 2.0 using either implicit or authorization code flow. I believe this means that somewhere in this flow a browser is opened where username and password must be entered. Also I need to give a redirect uri to this party, I'm not sure how to implement this in my current setup.
Anyone have an idea? More info about the API can be found here. https://accounting.twinfield.com/webservices/documentation/#/ApiReference/Authentication/OpenIdConnect

Usually the Authorization Code flow would be the way to go in your kind of application.
You will send a authentication request to their API(redirecting the user). They will authenticate the User and redirect the user back to your application, using the redirect URI you provided.
You can get an access token or ID token from their token endpoint using the code, your client id and your client secret.

Related

Automate OneDrive Authentication with AAD MFA with python

I'm finding a way to automate the authentication from AAD with python.
In the past i used username and password for login to OneDrive and it worked properly. Here is the code:
pca = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY_URL)
token = pca.acquire_token_by_username_password(USERNAME, PASSWORD, SCOPES)
Now, that i have two factor authentication i cannot use the same code to access OneDrive account.
I've searched the internet but all the solutions that i found requires to open the browser, and i can't do this because python script is a chronjob and runs in the late night. I need a solution that works in "background" without any action required.
Possibly it's better if there is a solution with MSAL library due to some permissions that i should request if i would change the library.
Thanks for the help!
You might consider using the Client-Credentials Grant flow or OAuth2. You would have to modify your cronjob to move away from fetching a token on behalf of the user and update it to acquire a token as the application using the application's identity (the app registration done in AAD). Upgrading to client-credentials flow, which is actually designed for scenarios similar to yours, will help you in situations where you cannot afford user interaction and you want the service to work in the backend.
For more information on Client-Credentials flow, check here.
Also, you can refer to the following python app that implements client-credentials flow:
Call Microsoft Graph API using App Client Secret
Call Microsoft Graph API using App Client Certificate:

How do I access the Salesforce API when single-sign on is enabled?

I'm attempting to make SOQL queries to the Salesforce API using the Python salesforce_api and simple-salesforce modules. I had been making these requests with a client object:
client = Salesforce(username='MY_USERNAME',
password='MY_PASSWORD',
security_token='MY_SALESFORCE_SECURITY_TOKEN')
a = client.query("SELECT something FROM some_object_table WHERE some_condition")
However, my company recently restricted Salesforce sign-in through SSO only (you used to be able to login directly to Salesforce without SSO), and the funciton is throwing either:
simple_salesforce.exceptions.SalesforceAuthenticationFailed: INVALID_SSO_GATEWAY_URL: the single sign on gateway url for the org is invalid
Or:
salesforce_api.exceptions.AuthenticationMissingTokenError: Missing or invalid security-token provided.
depending on which module I use. I suspect this is because of the SSO implementation.
I've seen the docs about creating a new app through Okta, but I need to authenticate and access the API of an existing app. What is the best way to access this API with Okta IdP enabled? It there a way to have a get request to Okta return an access token for Salesforce?
Uh. It's doable but it's an art. I'll try to write it up but you should have a look at "Identity and Access Management" Salesforce certification, study guides etc. Try also asking at salesforce.stackexchange.com, might get better answers and Okta specialists.
I don't know if there's pure server-side access to Okta where you'd provide OAuth2 client, secret, username and password and it'd be silently passed to login.
If your app is a proper web application that needs human to operate - you can still make it work with SSO. You'd have to read about OAuth2 in general (you saw it on the web, all the "login with Google/Facebook/LinkedIn/Twitter/..." buttons) and then implement something like this or this. Human starts in your app, gets redirected to SF to enter username and password (you don't see password and you don't care whether he encountered normal SF login page or some SSO), on success he/she is redirected back and you receive info that'll let you obtain session id (sometimes called access token). Once you have access token you can make queries etc, it's just a matter of passing it as HTPP Authorization Bearer header (simple-salesforce docs mention session id at top of the examples).
Look, I know what I've written doesn't make much sense. Download Data Loader and try to use it. You might have to make it use custom domain on login but there is a way for it to still work, even though you have SSO enforced. Your goal would be to build similar app to how Data Loader does it. This might help a bit: https://stackoverflow.com/a/61820476/313628
If you need a true backend integration without human involved... tricky. That might be a management problem though. They should not enforce SSO on everybody. When Okta's down you're locked out of the org, no way to disable SSO. You should have a backup plan, some service account(s) that don't have SSO enforced. They might have crazy password requirements, maybe login only from office IP address, whatever. It's not a good idea to enforce SSO on everybody.
https://help.salesforce.com/articleView?id=sso_tips.htm
We recommend that you don’t enable SSO for Salesforce admins. If your
Salesforce admins are SSO users and your SSO server has an outage,
they have no way to log in to Salesforce. Make sure that Salesforce
admins can log in to Salesforce so that they can disable SSO if
problems occur.
(If you have a web app and it's embedded as Canvas in SF - there's another clean way to have the session id passed to you. Again - this works only if you have a human rather than backend integration)
If you check the profiles in SFDC and uncheck the box that requires SSO.
"is single sign-on Enabled [] Delegate username and password authentication to a corporate database instead of the salesforce.com user database. "

Spotify authorization code (not access token) is expiring - how can I circumvent this?

I am developing an app that creates a public Spotify playlist for a user who has given proper authorization to do so.
I am using Flask and Python requests library to accomplish this, but after I've sent a few consecutive POST requests to get an access token from Spotify (using authorization code obtained from previous logic), it begins to fail. I am referring to Step 4 of Authorization Code Flow from this link: https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow
I know the authorization code is valid, because it doesn't fail for the first few times I run the request (maybe 5-10 times).
When I print the response from the POST I get the following:
{'error_description': 'Authorization code expired', 'error': 'invalid_grant'}
I assume I am not using the authorization code fast enough to get an access token (after repeatedly failing on code logic before the access token POST request, I guess?) but how am I supposed to reset and refresh the authorization code so I can keep making requests repeatedly? Any info on how long I am disabled and generally good programming practice to avoid this scenario?
When you use the authorization code to get your access token, you will also get a refresh token back in the same message. Use that refresh token to request new access tokens, when the access tokens expire.
How to use the refresh token is written on the same page you linked to, just a bit further down: https://developer.spotify.com/web-api/authorization-guide/#request-access-token-from-refresh-token
I agree that this is not the easiest to understand, but there are good reasons for all these things. It is also a standard called OAuth2, which many websites use to let users authorize apps to access their data, so it is useful in a lot of places.
In this specific case: "why do I need a refresh token to get an access token, I already have an authorization code to get an access token?", it is because the authorization code has leaked to the outside because it was returned to you via the user's browser.
An authorization code is obtained when the user grants permission for the third-party application (the Client). As per OAuth's 2.0 specification the authorization code must be used once and it's recommended that it have a maximum lifetime of 10 minutes to mitigate security flaws.
Read more about authorization code here:
https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2
On the other hand, instead of boring the user to go through all the OAuth 2.0 dance again (to authenticate and to grant permissions), the server side of Client application can use Refresh Tokens to ask for a new token when it's expired.
More about refresh tokens can be found at section 10.4 of OAuth 2.0 spec.
https://www.rfc-editor.org/rfc/rfc6749#section-10.4

Is it possible to use the Spotify Web API to write a desktop application without a callback URI?

I would like to write a simple desktop application for personal use that uses the Spotify Web API to build playlists.
As far as I can tell, however, there's no way to use the API without providing a callback URI, which I don't have, seeing as I don't have a domain or server of any kind (other than my personal computer).
Is there a way to use the API without a URI?
If not, what is the best way to set up a callback URI? I don't have much of any experience working with web applications or client / server stuff, and the APIs I've used in the past haven't required any kind of callback.
Some background first, this answer became a bit longer than what I anticipated.
You need an access token. There are three ways to retrieve an access token; Authentication Code flow, Client Credentials flow, and Implicit Grant flow. These are all part of the oAuth 2.0 specification, each with its own purpose.
Since you're going to modify a user's account, you need that user's permission. Now, if you didn't do any actions that required user permissions, you could've used the Client Credentials flow. That's probably the easiest flow to learn since it just requires a request from your server to Spotify's server, and the response contains an access token. No callback/redirect URI is necessary.
As I'm sure you've read, the Authentication Code flow and Implicit Grant flow both require a callback URI. This is because a flow that includes a user, and the callback URI is where Spotify redirects the user after they have entered their password on Spotify's site.
The Authentication Code flow and Implicit Grant flow has benefits and drawbacks. Access tokens retrieved through the Authentication Code flow can be refreshed, but both return tokens that are valid for one hour. This means that a user that's authenticating using the Implicit Grant flow must reauthenticate after an hour. However, the Authentication Code flow does require some backend work, since it needs to make a request to exchange a code given from Spotify's server for an access token. The Implicit Grant flow is more straight forward - you get the access token and off you go.
The callback URI can be a localhost address, so if your desktop application would spin up a web server locally you could handle the callback on the same machine that the application is running on. (It's probably a good idea to not run the web server on port 80 since that might be used by something else.)
There's skeleton code for each of this authentication flows available on Github, see web-api-auth-examples. Read more about the flows in our Authorization Guide. If you choose to run a web server on the user's machine, I recommend that you use the Implicit Grant flow since that doesn't include any server-to-server requests, so you won't have to expose your client_secret exposed in the code. (As opposed to the Authorization Code flow.)
Also, since you're coding in Python, I recommend that you have a look at spotipy, a wrapper around the Web API packed with convenient methods that'll save you some time. If you do go ahead with the Implicit Grant flow, you should have a look at spotify-web-api-js, which has a similar purpose. Note that these wrappers are not at all required to work with the Web API but they'll make your life easier.

How to test a website for performance testing having google oauth login?

I have a website and I need to test it with 250 users. However, I am using google login via OAuth2. The website is hosted on Google App Engine.
I am stuck at this login part. After we log in we get and access token from Google that is passed to Google APIs via the Authorization: Bearer header. We use the access token in the application to get user details and access other google apps for that user. I don't know how to get that access token using my external script.
One option is to mock / stub this part of your application out during testing. For instance, you can provide a certain header that tells your application that you're in test mode and instead of calling the real google APIs, it calls a mock API instead. If your application is setup for dependency injection this could be trivial, otherwise, it may involve monkey-patching or similar.
Another option is to use an OAuth2 Service Account and acquire access tokens for a bunch of users in a test Google Apps domain. Your test script can do this and then just pass the access tokens just as a client normally would.

Categories