How to securely get access token from Marketo - c#

Marketo Rest API exposes a GET call to oauth/token uri, which exposes clientId and clientSecret parameters to all internet hops between the 2 networks. Am I missing something or is there a way we can securely get an access token?

Marketo also has a POST method for this endpoint where you can send the clientId and clientSecret as x-www-form-urlencoded POST parameters
curl -X POST -H "Cache-Control: no-cache" -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=MY_CLIENT_ID&client_secret=MY_CLIENT_SECRET&grant_type=client_credentials' "https://MY_MARKETO_URL/identity/oauth/token"

I actually got my facts wrong, basically this get call is https, and query parameters will be sent encrypted over the wire once it establishes a secure connection to the server. Only caveat I found is that a server admin can read the credentials in clear text if browsed server file system which is a low risk.

Related

Basic Authorization in header vs Username and password in body

I am facing two different situations . First method i can send username and password in body as model . Second method is to use basic auth in Header . Both methods are working fine.
Both methods are used only for first call just to authenticate, and the api returns a jwt token.
First Method:
curl -X 'POST' \
'https://localhost:7122/api/Authentication/token' \
-H 'accept: text/plain' \
-H 'Content-Type: application/json' \
-d '{
"userName": "test",
"password": "test"
}'
Second Method:
curl -L -X POST 'https://localhost:7122/api/Authentication/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Basic ZzI0N2NmbnlwYzV3cmszaHAwZnU2cTk3N2YzZzYxY2hnODV1NzJzZmJkb3c3LmFwcHMudml2YXBheW1lbnRzLmNvbTowYk9xOHRkMzhMQVF4b3ptaWVqUDYwUzdzQnJkVkQ=' \
--data-urlencode 'grant_type=client_credentials'
Are they rules for what should i use in jwt token?
What is good practice to use?
Just to ensure everyone's on the same page let me outline a typical JWT-authentication workflow here:
User calls an anonymous POST API (no authorization required), with a username and password. API then returns a JWT. That's your Login API at line 3.
All other API calls require authorization, and so the client sends that as Bearer [JWT]. The server then determines if the token is valid and if not returns 401.
As I understand the question, you're asking whether, for (1), it's better to send the u/p through the authorization header using the Basic Authentication protocol (base64 etc) or to just post it in plaintext in the body of the login request.
There are two drawbacks I can see with using the auth header-
Sometimes headers are logged along the way while request bodies rarely are. Grant you, I think it would be unusual (if not unforgivable) for a system to be logging auth headers, but it's possible. The base64 encoding of course provides no security.
I have had difficulty in the past with basic auth headers actually going through. I'll just refer you to this thread which explores some of the possible pitfalls.
Other than the possibe logging issue, I can't think of any inherent issues with using one vs. other though. FWIW, I see APIs all the time that use the plaintext body approach while I've never seen an API that has you log in using basic auth and then returns a JWT.
Hopefully it goes without saying that you MUST ensure your APIs are only accessible through HTTPS. Otherwise you're hosed no matter where you put the password.
That said, if you're designing this from scratch and have access to both ends of the system and they will always be in sync, I'd consider sending a hashed password, regardless whether you use the auth header or POST body. As long as your client and server agree on the hashing method and iteration count, that significantly lowers the impact of that data possibly leaking or being logged somewhere. This would require a little homegrown security work though.
As for your other question,
Are they rules for what should i use in jwt token? What is good practice to use?
Rules? No. Conventions, definitely. Ultimately it's whatever information the application needs to be able to trust the user and give them access. These will be in the form of "claims". There's lots of literature on this but the definitive authority would be the RFC.

How to call a Google Vertex AI endpoint with an Api Key with c# and curl

from a c# program i want to call my vertex ai endpoint for prediction with an api key (via "Google Cloud"/Credentials/API Keys" )). I gave the api key access to Vertex AI and as a test everything else too.
calling it with curl or c# i get the error that the service expects an "OAuth 2 access token " or something else.
CURL:
curl -X POST
-H "apikey=..mykey..." -H "Content-Type: application/json" https://.....googleapis.com/v1/projects/[PROJECT_ID]/locations/europe-west4/endpoints/[ENDPOINT_ID]:predict
-d #image.json
ERROR:
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. ...
}
MY QUESTION:
Is there a way to use the Apikey for authentication to vertex ai?

Authentication; accessing web service from .net core (5.0)

I'm trying to access a jira server from .net (core 5.0 on Windows) desktop application.
If I use curl (WSL) like so:
curl -u userid:pwd -X GET -H "Content-Type: application/json" https://jira.jira.com/rest/agile/1.0/board
JSON is returned.
I tried to something similar in .NET:
var wc = new WebClient();
wc.Credentials = new NetworkCredential("userid", "pwd");
wc.Headers.Add("Content-Type", "application/json");
var reply = wc.DownloadString("https://jira.jira.com/rest/agile/1.0/board");
and the download call throws a 401.
Interestingly, if I take the "Authorization" header generated by curl and add it to the headers (wc.Headers.Add("Authorization", "Basic xxxxxxxxxxxx=");). The call works and returns JSON.
Two questions.
What does the 'Credentials' property do if it's not adding the header?
Is there a simply way to get the domain id info and pass on appropriate information so my application doesn't deal with user/pwd at all?
If you suggest MSAL for the second question please provide a simple example that doesn't require registering a client id (if possible).

Dropbox API App Authentication with .NET SDK

I've got a server-hosted .NET app that will need to connect to a single Dropbox account (on a schedule) and just overwrite a file there. In looking at the Dropbox authentication types, it states the following:
App Authentication
This type only uses the app's own app key and secret, and doesn't identify a specific user or team. The app key and secret are transmitted in place of a username and password using "HTTP basic access authentication".
Examples:
When supplying the app key and secret for App Authentication, the app key and secret are given in place of the HTTP username and password, respectively. This can be done either as separate strings, as shown in the first two examples below, or as an base64-encoded Basic authorization string in the Authorization header, as in the third example below.
Example 1:
curl -X POST "https://api.dropbox.com/1/metadata/link" -u "<APP_KEY>:<APP_SECRET>" \
-d
link="https://www.dropbox.com/sh/748egu7925f0gesq/AAHi80RJyhJFfkupnAU0wXuva?dl=0"
Example 2:
curl -X POST "https://<APP_KEY>:<APP_SECRET>#api.dropbox.com/1/metadata/link" \
-d
link="https://www.dropbox.com/sh/748egu7925f0gesq/AAHi80RJyhJFfkupnAU0wXuva?dl=0"
Example 3:
curl -X POST "https://api.dropbox.com/1/metadata/link" \
--header "Authorization: Basic <base64(APP_KEY:APP_SECRET)>" \
-d "link=https://www.dropbox.com/sh/748egu7925f0gesq/AAHi80RJyhJFfkupnAU0wXuva?dl=0"
Great! So I know it can be done without the whole OAuth authentication flow.....However, I can't seem to figure out how to perform App Authentication via the Dropbox.NET SDK by just supplying the AppKey and AppSecret.
Anyone have a code example of how to perform Basic Auth rather than OAuth against Dropbox?

Using the Google API .NET client with an existing access token

The use-case is the following: a mobile app is authenticating a user with Google and at some point, we need to publish a user's video to his YouTube account; for practical reasons, the actual publication should be done by the back-end (large files that are already stored there).
As the user is already authenticated by the app, the app just sends the user's access token to the back-end. Now my struggle is to find how to use this access token with the .NET client... So far I've tried to create instances of UserCredential from that access token but that doesn't seem to work. Also we don't need all the token refresh logic provided by UserCredential as we know that the access token is valid at this point.
Any help would be greatly appreciated, thanks!
Technically speaking you could just forward the access token, then when you want to call the api you just add the access token to the header as a bearer token
curl --request POST \
'https://youtube.googleapis.com/youtube/v3/videos?key=[YOUR_API_KEY]' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{}' \
--compressed
This could be done with manually with .net using a Http client.
However if you want to use the Google .Net client library you could do something like this.
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
scopes,
userName,
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
However you will need to do a few things. First off you need to make your own implmentation of FileDataStore which would accept an access token passed to it. I have a few samples of custom datastores here That you can have a look at they may help.
The second issue is that the client id and client secrete that you pass to the Google .net client library will need to be the same one that was used to create the access token to begin with. I am not 100% sure if this will be an issue as you are not passing a refresh token so the client library wont need to refresh the access token it just needs to use it.
There are other ways to create dummy credentials object for use with the Client library but this is the one that i have used in the past.
I dont personally think its a good idea for you to be passing access tokens around between servers in this manner. You really should have the user authorize your app properly.

Categories

Resources