Simulating Azure Scheduler with Basic Authentication - asp.net-mvc

How can I locally reproduce the https GET call that my Azure Scheduler job would execute that uses Basic Authentication with a username/password?
I know I can just type in the URL in the browser to hit the action in my MVC controller, but how does Azure Scheduler send the username/password?

If Azure Scheduler uses Basic Authentication then it will send the username and password as Base64 encoded Authorization header.
The username and password are combined into a string separated by a colon, e.g.: username:password
The resulting string is encoded using the RFC2045-MIME variant of Base64, except not limited to 76 char/line.
The authorization method and a space i.e. "Basic " is then put before the encoded string.
So for example if your username=john and password=secret, the Authorization header would look like this:
Authorization: Basic am9objpzZWNyZXQ=
So you should make the following HTTP request:
GET /yourcontroller/youraction HTTP/1.1
Authorization: Basic am9objpzZWNyZXQ=
Connection: close

Related

What type of authorization does UiPath Cloud use?

I am recently working with Uipath Orchestrator API and I see that they use Bearer token to authenticate. But I am confused and I do not know if this way of authentication is oAuth or it can just be called Bearer Authentication.
So for API authentication, it depends on what orchestrator you are using.
On-Premise
If you are using an on-premise installation of Orchestrator you would send the following JSON body to your Yourorchestrator.com/api/Account/Authenticate
{
"tenancyName":"default",
"usernameOrEmailAddress":"your username",
"password":"your password"
}
you will get a JSON string returned and you want to extract the value for key result this is your authentication token.
Now that you are authenticated you can send your requests with the following header
Name - Authorization
Value - Bearer + your token from above
This is your authentication done.
Cloud
If you are using UiPath cloud instance of orchestrator you will need to send the following JSON body
{
"grant_type" : "refresh_token"
"client_id" : "ClientId"
"refresh_token" : "UserKey"
}
ClientId and UserKey are generated through the cloud instance of Orchestrator
You must also send the following header along with the JSON Body
Name - X-UIPATH-TenantName
Value - Your tenant logical name from orchestrator
Similar to the on-site orchestrator, this will return an authentication token, however, you will need to extract the value for key access_token.
To use this, you send the request with the following 2 headers
Name - Authorization
Value - Bearer + your token from above
Name - X-UIPATH-TenantName
Value - Your tenant logical name from orchestrator
There are some quite useful examples at https://postman.uipath.rocks/?version=latest
It can be quite fiddly to start with, and on-prem Orchestrator is definitely easier to connect with than Cloud orchestrator. I would definitely recommend using Postman to build your API calls

BigCommerce oAuth auth token request always returning 401

I can not figure out what I'm doing wrong. I'm developing an App for BigCommerce and can not get the simple oAuth exchange to work correctly.
The initial get request is being made to https://www.my-app.com/oauth/bigcommerce/auth. This is the code in the controller for that request. It's a Laravel 5.6 app:
use Illuminate\Http\Request;
use Bigcommerce\Api\Client as Bigcommerce;
class BigcommerceOAuthController extends Controller
{
public function auth(Request $request)
{
$object = new \stdClass();
$object->client_id = 'my-client-id';
$object->client_secret = 'my-client-secret';
$object->redirect_uri = 'https://my-app.com/oauth/bigcommerce/auth';
$object->code = $request->get('code');
$object->context = $request->get('context');
$object->scope = $request->get('scope');
$authTokenResponse = Bigcommerce::getAuthToken($object);
$storeHash = str_replace('stores/', '', $request->get('context'));
Bigcommerce::configure(array(
'client_id' => 'my-client-id',
'auth_token' => $authTokenResponse->access_token,
'store_hash' => $storeHash
));
echo "<pre>";
print_r($authTokenResponse);
print_r(Bigcommerce::getTime());
echo "</pre>";
}
}
Every time I try to install my draft app from the BigCommerce control panel, I get an error because $authTokenResponse is not an object. When I debug further into the Bigcommerce\Api\Connection class, I can see that the response from the server is empty, and the status is a 401, which means "Unauthorized".
I can't figure out why I am getting this error. As far as I can see, I'm doing everything right. I've tried urlencoding the string retrieved from $request->get('scope'), since that string becomes unencoded by Laravel, but that didn't seem to help.
I am also confused how this is even supposed to work at all. In the BigCommerce docs, they show this example POST request, which uses application/x-www-form-urlencoded Content-Type and passes the request body as a url encoded string:
POST /oauth2/token HTTP/1.1 Host: login.bigcommerce.com Content-Type:
application/x-www-form-urlencoded Content-Length: 186
client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&code=qr6h3thvbvag2ffq&scope=store_v2_orders&grant_type=authorization_code&redirect_uri=https://app.example.com/oauth&context=stores/{STORE_HASH}
However, if you inspect what's going on in the Connection class, you can see that the Content-Type is being set to application/x-www-form-urlencoded as the docs say, but the request body is being passed in as a json string, not a url string. Shouldn't the request be a url encoded string as the docs suggest?
A couple of things here to check:
Do you have a public URL where you can receive the Auth Callback?
If so, did the store owner registered the app successfully? https://developer.bigcommerce.com/api/registration
When you have the client_id and secret_id. You should have all of the details needed to send a POST request to the BC Auth Token Service at https://login.bigcommerce.com/oauth2/token
The content uses URL encode Make sure to URL encode your content. Be careful of of the encoding of & and = signs when those are actually being used as separators.
More details can be found in this post:
Can BigCommerce Private Apps use OAuth

Paw not finding access_token from OAuth proxy

I have a use-case where I need to spoof a white-listed Redirect URL locally when performing OAuth 2 authentication.
I'm running a very basic web-server coupled with a hosts file entry for the domain I'm spoofing. I'm able to correctly negotiate my tokens and return them to Paw, but Paw isn't picking up my access_token or refresh_token, it simply displays the raw response:
Here's my server code (with placeholders for sensitive data):
var http = require('http'),
request = require('request');
var PORT = 6109;
var server = http.createServer(function(req, res) {
var code = req.url.split('?')[1].split('=')[2];
request({
url: 'https://<access token URL>/oauth2/token?code=' + code,
method: 'POST',
form: {
'client_id': <client_id>,
'client_secret': <client_secret>,
'grant_type': 'authorization_code',
'redirect_uri': <spoofed redirect URL>
}
}, function(err, response, data) {
data = JSON.parse(data);
res.writeHead(200, {'Content-Type': 'application/json'});
res.write(JSON.stringify(data.result));
// I also tried this with the same end-result
// res.writeHead(200);
// res.write('access_token=' + data.result.access_token + '&token_type=' + data.result.token_type + '&refresh_token=' + data.result.refresh_token);
res.end();
});
});
server.listen(PORT, function() {
console.log('Server listening on port %d', PORT);
});
What am I missing? Why isn't Paw finding my tokens?
Here's my configuration for reference:
Some other noteworthy points:
The OAuth provider is non-standard and flubs quite a few things from the spec (my proxy exists in part to patch up the non-standard bits)
The domain for the Redirect URL is real, but the URL does not resolve (this is a part of the reason for the local hosts entry)
I'm not showing this part of the flow, but I am correctly completing the authorization step prior to being given the code value
I think you're probably confused between the Authorization URL and Access Token URL. When you're in Authorization Code grant type for OAuth 2, you're expected to have a user confirmation step in a web page (the Authorization URL).
Which makes me guess that instead, you're expecting instead to use the Password Grant or Client Credentials? Otherwise, if you want to use Authorization URL, you'll need to specify a webpage at the Authorization URL.
Note: I've tried your Node.js script in Paw using the two last grants I mentioned (Password Grant & Client Credentials), and it works nicely.
Update: Following the comments below, I understand more what you are doing. The Authorization Request should (if successful) return a 302 redirect response to the Redirect URL page, and append a code URL query param to it. It seems like you're returning a JSON response with the code instead, so Paw isn't catching it.
According to the OAuth 2.0 spec (RFC 6749), section *4.1.2. Authorization Response*, if granted, the code should be passed as a URL query param (i.e. a ?key=value param in the URL) to the Redirect URL when doing the redirection.
If the resource owner grants the access request, the authorization
server issues an authorization code and delivers it to the client by
adding the following parameters to the query component of the
redirection URI using the "application/x-www-form-urlencoded" format
Quoting the example from the spec, here's how the response of the Authorization Request should look like if it's a success (code is granted):
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz
I saw that the Redirect URL contains "my Spoofed Uri".
When we need to use authorization code flow, we provide the authorization code and redirect Uri.
When the URI you are providing does not match the URI saved for the client in Identity server, you will not be able to get the token as the URI does not match with the client authorization code.
For example : Consider client identity in the Identity server be:
Auth Code: "xyx"
Redirect Uri: "www.mylocalhost.com\xyz"
And in your example the combination you are providing is:
Auth Code: "xyx"
Redirect Uri: "<my spoofed uri>"
As these 2 wont match there will be no token received.
I believe if you use the correct URI that is registered with the client in the Identity server, you will be able to receive the token.

Authenticating to an API with a token

I'm working with the Zendesk API, an HTTPS-only, JSON API and authentication is required to update a resource, and the API supplies an API token to use when authenticating as different users. When updating a resource, I issue a PUT request over SSL, assign the appropriate JSON content to the request body, and specify the Content-Type request header as application/json.
Next, the API instructs its users to authenticate as the end-user by either using the user's email and password (which I can't do for several reasons) or to use the user's email address along with the API token. The following is my attempt to authorize to the API with the Authorization header:
#id = params[:id]
#comment_body = params[:comment]
uri = URI.parse "https://{subdomain}.zendesk.com/api/v2/requests/#{#id}.json"
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Put.new(uri.request_uri)
req.body = '{"request": {"comment":{"value":' + "\"#{#comment_body}\"" + '}}}'
req['Content-Type'] = 'application/json'
#The following two lines do not work!
credentials = Base64::encode64("{user_email}/token:{api_token}")
request.headers['Authorization'] = "Basic #{credentials}"
response = http.request(req)
The API specifies that the format for authentication using the API token is {user_email}/token:{api_token}. I encoded that format with Base64::encode64 and passed it to the Authorization Header preceded with Basic, but the response is a 401 Unauthorized. However, replacing those two lines with req.basic_auth {user_email}, {user_password} works fine.
So my question is, how can I authenticate as a different user using the email and the given API token as authentication instead of supplying the user's email and password to req.basic_auth?
The googling I've done on the topic has revealed very little; apparently it's a lot more common to use the normal {username}:{password} format when dealing with the Authorization header than an API token.
Thanks in advance!!
Update: Weirdly, trying to authenticate as the end-user with req['Authorization'] = "Basic #{credentials}" does not return a 401 Unauthorized Error or a WWW-Authenticate header while trying to authorize as request.headers['Authorize'] = "Basic #{credentials}" does.
Finally figured it out after much head-banging and nearly throwing my laptop out the window. Suddenly, the answer seems incredibly obvious.
When using Net::HTTP, its basic_auth method can also accept tokens depending on the API, and the Zendesk API specifies that the format for using the API token is {email}/token:{token}. Basic authentication uses the format {username}:{password}, where the two fields are separated by a colon, meaning in Zendesk's case I can place {email}/token as the first argument and {token} as the second argument (instead of the username as the first argument and the password as the second argument), so the following code is correct:
req.basic_auth "{email}/token", "{api_token}"
I hope anyone who found this useful could leave a comment. Nice to know I spared someone from this frustration.

Tridion UGC service and oAuth authentication

I've a problem when trying to do a webrequest to UGC and authenticate using oAuth. I'm making a webrequest such as:-
WebRequest wr = WebRequest.Create("http://ugc.service/odata.svc/Ratings(Id=200)");
wr.Headers["authorization"] = "OAuth " + auth;
Where auth is my token returned from the access_token.svc. According to the documentation the token returned from the service should be something like:-
HufXeuUt%2FYYElA8SYjJOkUkrXxV9dyXRirmKhjW%2Fb%2FU%3D
However, what I'm being returned from access_token.svc is more like:-
{"access_token":"client_id%3dtestuser%26expiresOn%3d1361898714646%26digest%3d%2fW%2fvyhQneZHrm1aGhwOlgLtA9xGWd77hkxWbjmindtM%3d","expires_in":300}
I've parsed the JSON to extract various strings and attempted to pass these through to the authorization but whatever I try I get an error in the logs - "ERROR OAuth2AccessToken - Digest is wrong." Exactly what part of the token and in what format should I be passing through to authorization?
Many thanks
John
Like you mentioned, the protocol is this:
You make a post request to the access token end-point to get a token (you need to provide here your client_id and your client_secret as headers or as query parameters);
You get an answer similar to this: {"access_token":"sometoken","expires_in":300};
2.1 Worth knowing is that the token is url encoded and in UTF-8 format so, on Java side you need to do URLDecoder.decode("sometoken", "UTF-8"); while on .NET side you need to do HttpUtility.UrlDecode("sometoken", System.Text.Encoding.UTF8);;
Your next request needs to include the authorization header. On Java side you do builder.header("authorization", "OAuth " + decodedTokenString); while on .NET side you can use Client.Headers["authorization"] = "OAuth " + DecodedTokenString;
Worth mentioning is that the SharedSecret defined in the cd_webservice_conf.xml (/Configuration/AuthenticationServer/SharedSecret/) of the TokenAccessPoint needs to be the same as the SharedSecret defined in the cd_ambient_conf.xml (/Configuration/Security/SharedSecret/) of the (WebService)EndPoint.
Are you sure you decoded properly the token gotten from the server? Are you sure that you configured the proper SharedSecret in the two configuration files?
Hope this helps.

Resources