Workday OAuth - Error Unauthorized Client - javascript

I'm trying to create an OAuth integration with Workday, but am receiving an Unauthorized Client error. I enabled the API client, got secret and access keys, and configured a redirect URI pointing to my server.
When I visit https://impl.workday.com/myTenant/authorize?response_type=token&client_id=myClientID, I'm brought to a screen to allow this app access to my Workday, I hit accept, and am then redirected to my server. However, when I check my server logs showing the request URL and headers, this is what I'm seeing:
URL: /workday?error=unauthorized_client
Headers: { host: 'localhost:9001',
connection: 'close',
'cache-control': 'max-age=0',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
'sec-fetch-mode': 'navigate',
'sec-fetch-user': '?1',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'sec-fetch-site': 'cross-site',
referer: 'https://impl.workday.com/wday/authgwy/myTenant/authorize?response_type=token&client_id=myClientID',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9'
}
I expected to receive a header "Location: https://example.com/#access_token=someAccessToken&token_type=Bearer" but am getting the unauthorized client error.

Changing https://impl.workday.com/myTenant/authorize?response_type=token&client_id=myClientID to https://impl.workday.com/myTenant/authorize?response_type=code&client_id=myClientID solved the issue.

Related

How to send a Post request using javascript with headers and parameters?

I am trying to send a post request using Javascript, but the problem is that I do not seem to be able to add custom headers to the request.
The request that I want to send:
OPTIONS /startScan?domain=asite.com&user=38 HTTP/2
Host: MYHOST
Accept: */*
Access-Control-Request-Method: POST
Authorization: A_TOKEN
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Sec-Fetch-Dest: empty
Referer: http://localhost/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
note that MYHOST and A_TOKEN are in my case other values, but replaced them for security reasons.
The request that I send:
OPTIONS /startScan?domain=asite.comm&user=38 HTTP/2
Host: MYHOST
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Sec-Fetch-Dest: empty
Referer: http://localhost/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
The code that I use to send this:
var data = JSON.stringify({
"domain": "asite.com",
"user": 38
});
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "MYHOST/startScan?domain=asite.com&user=38");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Authorization", "A_TOKEN");
xhr.send(data);
The problem:
The problem now is that I am not able to add a custom header to this request. Instead of adding a header that is called Authorization I add a Access-Request-Control-Header which has authorization as value. I have tried using jQuery, XHR (as you can see) and Fetch, but no success with all of them.
Can anyone help me?

Default request headers get lost when using setRequestHeader

I send a request with javaScript. If I send it this way
var request = new XMLHttpRequest();
request.open("POST",/*some url*/);
/*here's nothing*/
request.addEventListener('load', function(event) {/*some magic*/});
request.send();
Chrome shows me this request headers as sent:
:authority: <some data>
:method: POST
:path: /
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
content-length: 0
origin: <some data>
referer: <some data>
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
If I try to add another header (by replacing /here's nothing/ with
request.setRequestHeader("auth", "token");
the request header sent seems to loose some data. It now consists of:
auth: token
Referer: <some data>
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
The "origin" get's lost, but I need it for my CORS handling. So why the hell does it get lost?
Any ideas appreciated
Thnaks #John for leading me this way:
Actually, XMLHttpRequest or fetch doesn't matter. But the fetch documentation lead me the right way.
The problem was, that my sever answered the "OPTIONS" request with a http 400, what messed up preflight. I adjusted it, so it handles CORS at an OPTIONS request correctly and sends it with a HTTP 200 and now everything works smoothly.

JS fetch unable to set headers

I have a react application connecting to a Spring Boot backend application, I use JWT to authorize the user at the backend. I am using fetch to make the calls between the front and backend.
Whenever I try to set the headers of the call all the headers get removed including the Cookie (which contains the JWT). I need to set the headers to specify the content-type of the request.
- Call when I do not set the headers (causing 415)
fetch code:
return fetch(`${urlApiGateway}${url}`, {
method: "POST",
body: body,
credentials: "include",
})
Call:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,nl-NL;q=0.8,nl;q=0.7
Connection: keep-alive
Content-Length: 13
content-type: text/plain;charset=UTF-8
Cookie: Authorization=Bearer_eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJjYXNwZXIubS50b3JlbjJAZ21haWwuY29tIiwiZXhwIjoxNjI1NDg2MzAzLCJpYXQiOjE2MjUzOTk5MDMsInVzZXIiOnsiaWQiOjIsIm5hbWUiOiJjYXNwZXIiLCJlbWFpbCI6ImNhc3Blci5tLnRvcmVuMkBnbWFpbC5jb20iLCJwYXNzd29yZCI6IiIsInBlcm1pc3Npb25zIjoiQURNSU4ifX0.JdW1M7d8HB71yvP7dupomN-bgD_484HHbxmfnOOmvqM
Host: localhost:8080
Origin: http://localhost:3000
Referer: http://localhost:3000/
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
As you can see the headers are present like 'content-type' and 'Cookie'.
- Call when I do set the headers to prevent 415
fetch code:
return fetch(`${urlApiGateway}${url}`, {
method: "POST",
body: body,
headers: { "Content-Type": "application/json" },
credentials: "include",
})
Call:
It seems to be making 4 call, 2 with the previous fetch settings which where the same (no headers set).
2 of the calls look like this
Provisional headers are shown
content-type: application/json
Referer: http://localhost:3000/
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
and 2 look like this
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,nl-NL;q=0.8,nl;q=0.7
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:8080
Origin: http://localhost:3000
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Where, as you can see, the headers are gone including the Cookie and content-type.
- Spring boot cors
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(allowOrigin, "http://localhost:3000")
.allowCredentials(true)
.allowedHeaders("*")
.allowedMethods("GET", "POST", "OPTIONS");
}
I hope someone can help :)
You must pass Authorization Bearer token as header. Try this:
let yourAuthToken = .... // get bearer token from where you store it
return fetch(`${urlApiGateway}${url}`, {
method: "POST",
body: body,
headers: {
'Authorization' : 'Bearer ' + yourAuthToken
}
})
It hadn't anything to do with the js code, it was my cors settings on the backend side. My authorization filter was also being applied to the OPTIONS request which caused a cors error (no http ok status), after changing this it was fixed.
Thank you to all who tried to help me.

Microsoft Owin Cors allow all not working in Chrome for Web API

I have created on JS SPA which calls Web API. I am using CORS to allow all request for Web Api using tag "assembly: OwinStartup" and "app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);"
Complete application here
For Edge request is successful whereas in Chrome it is not. I am getting error: Failed to load https://localhost:44373/api/location?cityName=dc: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:44392' is therefore not allowed access.
Interesting part is I am unable to see any "Access-Control-Allow-Origin" request header for both in Developer tool.
For Chrome:
:authority:localhost:44373
:method:GET
:path:/api/location?cityName=dc
:scheme:https
accept:application/json, text/plain, /
accept-encoding:gzip, deflate, br
accept-language:en-US,en;q=0.9,bn;q=0.8
cache-control:no-cache
origin:https://localhost:44392
pragma:no-cache
referer:https://localhost:44392/
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36
For Edge:
Accept: application/json, text/plain, /
Accept-Encoding: gzip, deflate, peerdist
Accept-Language: en-US
Host: localhost:44373
Origin: https://localhost:44392
Referer: https://localhost:44392/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393
X-P2P-PeerDist: Version=1.1
X-P2P-PeerDistEx: MinContentInformation=1.0, MaxContentInformation=2.0
My start up page looks like this
You have to use this line of code as the first statement in the startup class --
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
...
...
...
My guess for it "working" in Edge is because it's detected localhost and decided not to do a CORS check; but Chrome will always do the check.
Anyways, you're not seeing the header because its not there. To get it working, do the following:
Add these 2 packages: Microsoft.AspNet.WebApi.Owin and Microsoft.Owin.Host.SystemWeb
Comment out GlobalConfiguration.Configure(WebApiConfig.Register); from the global.asax file because we want to use OWIN for Web API.
Replace Configuration() with this code in your StartUp:
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseWebApi(config);
}

How to get header value in java

I have written a servlet Filter in which I am trying to get the value of custom header=samlRequest, From rest client/postman chrome plugin i am getting the value of samlRequest, but using ajax call i have provide samlRequest key and its value but in java i am getting the only key samlRequest in "Access-Control-Request-Headers", how to get value of samlRequest.
$.ajax({
url: "http://indlin500.corp.test.com:31000/test/Portal/index.html",
type: "GET",
headers: { 'samlRequest': 'eJzVWVlz4roSfs6/oJhHJvECBkMRTsk2+2ow68stY8u2wBuWjQ2//srsyUlmJufOramTSjm41f '},
beforeSend: function(xhr){xhr.setRequestHeader('samlRequest', 'eJzVWVlz4roSfs6/oJhHJvECBkMRTsk2+2ow68stY8u2wBuWjQ2//srsyUlmJufOramTSjm41f ');},
success: function() { alert('Success!' + authHeader); }
});
FirewalledRequest[
weblogic.servlet.internal.ServletRequestImpl#4f839843[ OPTIONS
/testsOSS/Portal/index.html HTTP/1.1 Connection: keep-alive
Access-Control-Request-Method: GET Origin: http://10.19.121.17:7001
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Access-Control-Request-Headers: authorization, samlrequest,
x-partnerkey Accept: / DNT: 1 Referer:
http://10.19.121.17:7001/authentication-uxf-login-0.0.1-SNAPSHOT/customLoginPage.html Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8
]]
Using chrome rest client plugin I am getting samlRequest in the header with value i have provided.
FirewalledRequest[
weblogic.servlet.internal.ServletRequestImpl#24d746a[ GET
/testOSS/Portal/index.html HTTP/1.1 Connection: keep-alive
Cache-Control: no-cache samlRequest: eJzVWVlz4roSfs6/oJhHJvECBkMRTsk2+2ow68stY8u2wBuWjQ2//srsyUlmJufOramTSjm41f User-Agent: Mozilla/5.0
(Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/55.0.2883.87 Safari/537.36 Postman-Token:
ce7765d0-94b5-a1e1-d6ba-2abada3dfdd6 Accept: / DNT: 1
Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8
]]
When you make a cross-origin request from browser, the browser makes a preflight request before the actual request. It is an OPTIONS request, unlike the intended GET request.
Try adding a CORS filter before the actual filter which will reply OK for any OPTIONS request. A sample code can be found here :
https://amodernstory.com/2014/12/27/using-cors-headers-with-java-example/
by the way, you don't need to set header in request twice. You can remove the beforeSend block from the ajax request.

Categories

Resources