How to pass user authentication of a private dataset through SODA API? - soql

I need to access a private data set in socrata using SODA API. Suppose below link is the data set
https://data.cityofchicago.org/resource/xxxx-xxx.json
I get the following error when try this.
"error" : true,
"message" : "You must be logged in to access this resource"
I have valid credentials to access the data set. But how can I pass it through SODA API calls?
I tried the below code but it doesn't work.
https://data.cityofchicago.org/resource/xxxx-xxx.json?$username='myname'&$password='pwd#123'

You'll need to use either HTTP Basic or OAuth 2.0 to authenticate. We have details on how to do that on the developer portal.
Make sure you also provide an application token, as detailed in those docs.

You need to pass Secret-Token and AppToken with the query string.
How to Get secret Token
Log in to your portal and select "Create new Application"
Enter https://data.cityofchicago.org/resource/xxxx-xxx.json in the "website" field.
Save it.
Go to "Manage" and get your AppToken and SecretToken from under "Manage".
Now, pass the app token and secret token in the URL according to socrata developer document syntax:
https://sandbox.socrata.com/oauth/access_token
?client_id=YOUR_AUTH_TOKEN
&client_secret=YOUR_SECRET_TOKEN
&grant_type=authorization_code
&redirect_uri=YOUR_REDIRECT_URI
&code=CODE
I am also looking for an answer for the same question. After passing the app token I can access public DB but can not access Private DB.

Related

HTTP Connector in Microsoft Power Automate - Login against Azure AD app registration on behalf of user not working

I hope you are doing fine :)
I have the following problem/problems.
I have created a dummy (robot) user. In Azure AD there is an App Registration with some Power BI delegated permission services.
I want to automate the deletion of a push dataset via a HTTP request.
For this, I need to authenticate against that App Registration from Azure AD. With postman, everything worked perfectly, I got the token as a response.
Then, I tried to make the same request using the HTTP connector in PowerAutomate.
I get the following error
{"error":"invalid_request","error_description":"AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: e6d68953-ce1c-4217-856c-ae3aada82e00\r\nCorrelation ID: f50db4d9-d5bb-4396-af11-214717721f43\r\nTimestamp: 2022-10-26 19:12:48Z","error_codes":[900144],"timestamp":"2022-10-26 19:12:48Z","trace_id":"e6d68953-ce1c-4217-856c-ae3aada82e00","correlation_id":"f50db4d9-d5bb-4396-af11-214717721f43","error_uri":"https://login.microsoftonline.com/error?code=900144"}
The connector looks like this->
I have tried other ways as well.
The following error ->
{"error":"invalid_grant","error_description":"AADSTS50126: Error validating credentials due to invalid username or password.\r\nTrace ID: fec65949-0701-4727-af3b-2c2b8eb73a00\r\nCorrelation ID: 42c6c04b-98be-477d-8d36-52a01a473a40\r\nTimestamp: 2022-10-26 19:23:50Z","error_codes":[50126],"timestamp":"2022-10-26 19:23:50Z","trace_id":"fec65949-0701-4727-af3b-2c2b8eb73a00","correlation_id":"42c6c04b-98be-477d-8d36-52a01a473a40","error_uri":"https://login.microsoftonline.com/error?code=50126"}
I get from the the next HTTP connector inputs. I tried creating a query out of the previous json. It says the username or password are invalid but I logged in successfully for a number of times with those exact credentials. That I am sure of.
The dummy inputs in the picture are used to avoid the real ids, username and password.
This worked for me ...
Add a header setting Content-Type to application/x-www-form-urlencoded and add the URL form encoded content string like thus ...
client_id=<CLIENT_ID>c&grant_type=password&username=<USERNAME>&password=<PASSWORD>&scope=User.read
If you're using the password grant type approach, you shouldn't need a client secret, just the client ID.

ADFS 2016 On behalf of flow : cannot get any user informations

I'm trying to implement the "on behalf of" flow in an application using ADFS 2016 as STS. As a reference, I look at this Microsoft tutorial (https://learn.microsoft.com/en-ca/windows-server/identity/ad-fs/development/ad-fs-on-behalf-of-authentication-in-windows-server). It's working as it should, I can login into my web application and then use my original access token in UserAssertion to generate a new access token with the proper audience to call my API BUT I found absolutely no way to include any user informations (sub, name, email, upn etc.) into the access token for my API, even if I set claim rules into my ADFS configurations for the API.
I checked the communication between my app and adfs using Fiddler and everything looks like the informations in the tutorial. See the screen shot of the "on behalf of" request below :
Here's the resulting access token :
Finally, here's the code I use to generate my new access token :
private async Task<string> GetAccessToken(ClaimsPrincipal user, string originalAccessToken)
{
var authority = "[authority]";
var context = new AuthenticationContext(authority, false);
string userName = user.FindFirstValue("upn");
var userAssertion = new UserAssertion(originalAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer",userName);
var cc = new ClientCredential("https://localhost:44387/", "[client_secret]");
var result = await context.AcquireTokenAsync("https://localhost:44339/", cc, userAssertion);
return result.AccessToken;
}
Have you struggle with that scenario and if yes, did you find a way to fix this ?
Thanks
I've only used the Microsoft On Behalf Of flow with Azure AD and not ADFS, but it looks like you need to send a more detailed scope in your User Info request.
Maybe try sending 'openid profile email', to indicate that you want that type of detail, as in Section 17 of my blog post. Of course this assumes that this type of data has been registered for all users.
TROUBLESHOOTING
Looks like one of these will be the cause:
A suboptimal Microsoft library that does not allow you to send the required scope
Or ADFS 2016 perhaps lacks the scope features that work correctly in Azure AD
I would concentrate on making extra sure you are sending the correct form URL encoded request message, using a tool such as curl, Postman or a plain C# HttpClient. Here is the code I used to send the correct scope - using an open source library rather than a Microsoft one:
Sample NodeJS Code
If you can get the scope sent correctly then you should have a resolution either way:
Either you get the correct data and can update your code
Or the behaviour you want is not supported by ADFS
Good luck ...

Can I use my test environment merchant ID and keys to test a flex microform post?

I'm getting started understanding what's required for Cybersource's Flex Microform integration. But to start with, I'm hoping to be able to see a valid response using my merchant ID, shared secret key and the general key that comes with generating the secret on the cybersource api reference page: https://developer.cybersource.com/api-reference-assets/index.html#flex-microform_key-generation_generate-key
This is using the HTTP Signature method and ChasePaymentech (default) processor.
If I use the default settings they supply and choose to do a test POST to here https://apitest.cybersource.com/flex/v1/keys?format=JWT&
The JSON response is good with no complaints of authentication.
If I try to do the same POST with my test environment merchant ID and keys I generated in my merchant environment here: https://ubctest.cybersource.com/ebc2/app/PaymentConfiguration/KeyManagement the POST response will return a 401 with this JSON:
{
"response": {
"rmsg": "Authentication Failed"
}}
Is this developer.cybersource.com site a valid place to perform this kind of test? Are there any other steps I need to do in the merchant account to have this Authenticate?
I'm just getting started on figuring out the CyberSource Flex Micro Form code out myself and it's pretty straight forward from what I can see. If you don't have the proper SDK already pulled in, you can fetch it from https://github.com/CyberSource
I had to use Composer to fetch all the dependencies but once I did, I was able to load up the microform checkout page in my browser window successfully. Make sure you edit the ExternalConfiguration file with your credentials that you setup in CyberSource.
The apiKeyId value is the value you can find in your CyberSource account under Key Management. This is the value with the dashes in it.
The secretKey value is the value you should have downloaded from CyberSource that is your public key. This is the value without the dashes and probably has a few slashes / in it.
That's all I had to do in my setup to get the first successful authentication / token on my end.

Bad Argument, Invalid Subscription Key when trying to add key from Azure

I am trying to set up my LUIS app in luis.ai (because it seems like I can't set it up in Azure directly?). Anyway, I have created a Language Understanding Intelligent Service (LUIS) (preview) resource, but when I enter one of the keys from that resource into "My Keys" in luis.ai, I get this error: "Bad Argument, Invalid Subscription Key"
Also, I just tried to publish an app with the bootstrap key and got the following errors:
{ "statusCode": 401, "message": "Access denied due to invalid subscription key. Make sure to provide a valid key for an active subscription." }
As provided in comments, the solution is to use a correct end-point. This is not clear anywhere, but for the luis.ai portal, I have to use WestUS endpoint.
If I change to useing eu.luis.ai, I have to use the WestEU end-point.
To use european LUIS endpoint within Bot Builder C# SDK, just modify Luis Model parameters as follows:
[LuisModel("YOUR-LUIS-APP-ID", "YOUR-LUIS-EUROPEAN-KEY", domain:
"westeurope.api.cognitive.microsoft.com")]
Note that you'll need to export your LUIS app over EU.LUIS in order to access the correct endpoint.
Hope it helps.

Get refresh token google api

I can't get my refresh token with my code. I can only get my access token, token type etc.,
I have followed some tutorials like putting access_type=offline on my login URL:
echo "<a href='https://accounts.google.com/o/oauth2/auth?"
. "access_type=offline&client_id=123345555.apps.googleusercontent.com& "
. "scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/plus.me&response_type=code& "
. "redirect_uri=http://www.sample.com/sample.php&state=/profile'>Google</a>";
and my fields in getting the access token:
$fields=array(
'code'=> urlencode($authcode),
'client_id'=> urlencode($clientid),
'client_secret'=> urlencode($clientsecret),
'redirect_uri'=> urlencode($redirecturi),
'grant_type'=> 'authorization_code',
);
but I can't get refresh_token, just the access_token, token_type, id_token and expires_in.
Found out by adding this to your url parameters
approval_prompt=force
Update:
Use access_type=offline&prompt=consent instead.
approval_prompt=force no longer works
https://github.com/googleapis/oauth2client/issues/453
If I may expand on user987361's answer:
From the offline access portion of the OAuth2.0 docs:
When your application receives a refresh token, it is
important to store that refresh token for future use. If your
application loses the refresh token, it will have to re-prompt the
user for consent before obtaining another refresh token. If you need
to re-prompt the user for consent, include the approval_prompt
parameter in the authorization code request, and set the value to
force.
So, when you have already granted access, subsequent requests for a grant_type of authorization_code will not return the refresh_token, even if access_type was set to offline in the query string of the consent page.
As stated in the quote above, in order to obtain a new refresh_token after already receiving one, you will need to send your user back through the prompt, which you can do by setting approval_prompt to force.
Cheers,
PS This change was announced in a blog post as well.
It is access_type=offline that you want.
This will return the refresh token the first time the user authorises the app. Subsequent calls do not force you to re-approve the app (approval_prompt=force).
See further detail:
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
This is complete code in PHP using google official SDK
$client = new Google_Client();
## some need parameter
$client->setApplicationName('your application name');
$client->setClientId('****************');
$client->setClientSecret('************');
$client->setRedirectUri('http://your.website.tld/complete/url2redirect');
$client->setScopes('https://www.googleapis.com/auth/userinfo.email');
## these two lines is important to get refresh token from google api
$client->setAccessType('offline');
$client->setApprovalPrompt('force'); # this line is important when you revoke permission from your app, it will prompt google approval dialogue box forcefully to user to grant offline access
For our app we had to use both these parameters access_type=offline&prompt=consent.
approval_prompt=force did not work for us
Hi I followed following steps and I had been able to get the refresh token.
Authorization flow has two steps.
Is to obtain the authorization code using https://accounts.google.com/o/oauth2/auth? URL.
For that a post request is sent providing following parameters. 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE + '&access_type=offline' Providing above will receive a authorization code.
Retrieving AcessToken and RefreshToken using https://accounts.google.com/o/oauth2/token? URL.
For that a post request is sent providing following parameters.
"code" : code,
"client_id" : CID,
"client_secret" : CSECRET,
"redirect_uri" : REDIRECT,
"grant_type" : "authorization_code",
So in your first attempt once you authorize the permissions you will be able to get the Refresh token. Subsequent attempts will not provide the refresh token. If you want the token again the revoke the access in you application.
Hope this will help someone cheers :)
OAuth has two scenarios in real mode.
The normal and default style of access is called online.
In some cases, your application may need to access a Google API when the user is not present,It's offline scenarios .
a refresh token is obtained in offline scenarios during the first authorization code exchange.
So you can get refersh_token is some scenarios ,not all.
you can have the content in https://developers.google.com/identity/protocols/OAuth2WebServer#offline
.
Since March 2016, use prompt=consent to regenerate Google API refresh token.
As mentioned in https://github.com/googleapis/oauth2client/issues/453,
approval_prompt=force has been replaced with prompt=none|consent|select_account
For those using the Google API Client Library for PHP and seeking offline access and refresh tokens beware as of the time of this writing the docs are showing incorrect examples.
currently it's showing:
$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true); // incremental auth
source: https://developers.google.com/identity/protocols/OAuth2WebServer#offline
All of this works great - except ONE piece
$client->setApprovalPrompt("consent");
After a bit of reasoning I changed this line to the following and EVERYTHING WORKED
$client->setPrompt("consent");
It makes sense since using the HTTP requests it was changed from approval_prompt=force to prompt=consent. So changing the setter method from setApprovalPrompt to setPrompt follows natural convention - BUT IT'S NOT IN THE DOCS!!! That I found at least.

Resources