cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
The Discovery Summit 2025 Call for Content is open! Submit an abstract today to present at our premier analytics conference.
Get the free JMP Student Edition for qualified students and instructors at degree granting institutions.
Choose Language Hide Translation Bar
View Original Published Thread

JSL / JMP 17: OAuth apparently generates invalid request

inreoh
Level II

I'm currently trying to obtain an OAuth2 token to authenticate for an external service (Snowflake database), but I'm running into some problems with this.

 

According to the documentation, this is supposed to work:

oauth2_token = New OAuth2 Token(  User( username ),  Password( password),  Client ID( client_id ),  Client Secret( client_secret ),  Token URL( "http://localhost:8008" ),  Grant Type("password"),  Scope("session:role-any"));

 

However, whenever I run this, I get back an HTTP/1.1 400 Bad Request INVALID_REQUEST:INVALID_REQUESTDESCRIPTION

To debug this, I started a locally running HTTP echo server and sent requests from Python (working code, verified with real OAuth2 server) and JMP, and I got back this:


Python

127.0.0.1 - - [05/Feb/2025 13:36:00] "POST / HTTP/1.1" 200 -
Host: localhost:8008
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 91
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <redacted>=


grant_type=password&username=<redacted>&password=<redacted>&scope=session%3Arole-any

 

 


JMP 17

 

127.0.0.1 - - [05/Feb/2025 13:36:56] "POST / HTTP/1.1" 200 -
Host: localhost:8008
User-Agent: libcurl-agent/1.0 (Windows NT 10.0.22631;x64)
Accept: */*
Content-Length: 102
Content-Type: application/x-www-form-urlencoded


client_id=<redacted>&redirect_uri=&response_type=token&scope=&state=<redacted>

 

As you can see, there's no Authorization header, and also, most of the request parameters (grant type, username, password, scope) are missing.
To me, it looks like JMP generates a bogus request, and therefore, the communication with the server fails. Is this assumption correct? Or am I doing something wrong?

Any help would be highly appreciated.

Kind regards
Frank

1 ACCEPTED SOLUTION

Accepted Solutions
inreoh
Level II


Re: JSL / JMP 17: OAuth apparently generates invalid request

With some fiddling, I got it to work; key changes from your suggestion:

- include Basic Auth

- use Form encoding instead of JSON (not 100% sure why JSON didn't work, though)

Working example:

client_id = "<redacted>";
client_secret = "<redacted>";
token_url = "https://someurl/token";
username = "<redacted>";
password = "<redacted>";
grant_type = "password";
scope = "session:role-any";

request = New HTTP Request(
    Method("POST"),
	URL(token_url),
	Username(client_id),
	Password(client_secret),
	Form(
	  Fields([[
	         "grant_type" => grant_type, 
	         "username" => username, 
	         "password" => password,
	         "scope" => scope
	         ]]
	         )
	)
);

request << Authentication Method( "BASIC" );

data = request << Send();
json = ParseJSON(data);


For the time being, that's ok (we're using a technical user, so no need to get the user's personal password), but we'll definitely look into more secure approaches.

Thanks a lot for your help!

View solution in original post

7 REPLIES 7
jthi
Super User


Re: JSL / JMP 17: OAuth apparently generates invalid request

@bryan_boone 

 

Not sure if these links will be helpful but Integrating Google Drive with JMP using HTTP Request might give some ideas. Also check out Get Authorization Header + New OAuth2 from Scripting Index (bryan mentioned these here https://community.jmp.com/t5/Discussions/Open-file-from-private-github-repository-authentication-nee...). There is also a bit more documentation in JSL Syntax Reference but no idea if this helpful at all https://www.jmp.com/support/help/en/18.1/#page/jmp/utility-functions.shtml?os=win&source=application...

-Jarmo


Re: JSL / JMP 17: OAuth apparently generates invalid request

Yes,

New OAuth2

is the way to go. I look to see if I can alias New OAuth2 Token to it.

If not, I'll deprecate New OAuth2 Token.

New OAuth2 does all the browser handshaking for you.

inreoh
Level II


Re: JSL / JMP 17: OAuth apparently generates invalid request

Thanks, New OAuth2() looks much better. I was successfully able to obtain a Refresh token with the "Client Credentials" flow.

However, I'm struggling with getting the Password flow to work. My current code looks like this:

client_id = "<redacted>";
client_secret = "<redacted>";
token_url = "https://someurl/token";
auth_url = "https://someurl/auth";
username = "<redacted>";
password = "<redacted>";
grant_type = "password";
scope = "session:role-any";
auth_fields = [=> ];
token_fields = [=> ];
                                          
oauth2 = New OAuth2();
oauth2 << Grant Type( "Password" );
oauth2 << Auth URL( auth_url );
oauth2 << Token URL( token_url );
                                     
oauth2 << Username(username);
oauth2 << Password(password);                                     
                                          
auth_fields["scope"] = scope;
auth_fields["client_id"] = client_id;
token_fields["client_secret"] = client_secret;
                                          
oauth2 << Auth Fields( auth_fields );
oauth2 << Token Fields( token_fields );

However, this results in HTTP/1.1 401 Unauthorized. 

For comparison, here's a working example in Python:

def get_token(username: str, password: str, client_secret: str) -> str:
    client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, client_secret)
    post_data = {
        "grant_type": "password",
        "username": username,
        "password": password,
        "scope": "session:role-any",
    }
    response = requests.post(TOKEN_URL, auth=client_auth, data=post_data)
    token_json = response.json()
    print(f"Got token: {token_json}")
    return token_json["access_token"]

I guess that somehow, JMP doesn't establish the HTTP Basic auth with client_id / client_secret. What am I doing wrong?


Re: JSL / JMP 17: OAuth apparently generates invalid request

I think you are talking about:
https://oauth.net/2/grant-types/password/
This discussion (on the reference) says there's a move away from this.

You can probably do it all with HTTPRequest (without New OAuth2) since there is no need to prompt using password grant type (ie, it goes directly against the token URL)

The equivalent JSL (to the python) I believe looks like this, but I can't test it.

client_id = "<redacted>";
client_secret = "<redacted>";
token_url = "https://someurl/token";
username = "<redacted>";
password = "<redacted>";
grant_type = "password";
scope = "session:role-any";

payload =[=>];
payload["grant_type"] = "password";
payload["username"] = username;
payload["password"] = password;
payload["scope"] = scope;

request = New HTTP Request(
	URL(token_url),
	Username(client_id),
	Passwordlient_id),
	JSON(payload)
);

data = request << Send();
json = ParseJSON(data);

 

 

 

inreoh
Level II


Re: JSL / JMP 17: OAuth apparently generates invalid request

With some fiddling, I got it to work; key changes from your suggestion:

- include Basic Auth

- use Form encoding instead of JSON (not 100% sure why JSON didn't work, though)

Working example:

client_id = "<redacted>";
client_secret = "<redacted>";
token_url = "https://someurl/token";
username = "<redacted>";
password = "<redacted>";
grant_type = "password";
scope = "session:role-any";

request = New HTTP Request(
    Method("POST"),
	URL(token_url),
	Username(client_id),
	Password(client_secret),
	Form(
	  Fields([[
	         "grant_type" => grant_type, 
	         "username" => username, 
	         "password" => password,
	         "scope" => scope
	         ]]
	         )
	)
);

request << Authentication Method( "BASIC" );

data = request << Send();
json = ParseJSON(data);


For the time being, that's ok (we're using a technical user, so no need to get the user's personal password), but we'll definitely look into more secure approaches.

Thanks a lot for your help!


Re: JSL / JMP 17: OAuth apparently generates invalid request

Great find! I wasn't quite sure which 17 I introduced Authorization Method (maybe a maintenance?)

inreoh
Level II


Re: JSL / JMP 17: OAuth apparently generates invalid request

Small (but important) correction: it seems my approach only works with JMP 18, not with JMP 17.
Apparently, "Authorization Method" was introduced only in JMP 18. When trying to use the approach in JMP 17, I get:

Unrecognized message in access or evaluation of 'Authentication Method' , Authentication Method( "BASIC" ) /*###*/


I re-checked the documentation:
- the JMP 17 docs contain no mention of "Authentication Method" whatsoever
- the JMP 18 docs contain one example of "Authentication Method" in a PI call

(I hadn't noticed this before because apparently, the token from my JMP 18 tests was stored inside the JMP file / data table, and therefore, JMP 17 happily used the old token even though its own attempt to obtain a new one failed)