Getting systemtoken without a valid callback url

Hello, 

When developing a customApp for Online we whitelisted http://localhost/myApp so that i could use this as the callbackUrl and receive the systemToken (which is a part of the callback). 
The reason was that I'm running a console application that does not have a dedicated hostname/address and I need to use the systemToken to do my magic towards SuperOffice. There was no reason to set up a hostname/DNS-routing since it's never used in the console application after the systemToken is retrieved. 

When registering the app for production the callback is now defaulted to: 
https://online.superoffice.com/login/final/somethingrandom 

I guess whitelisting http://localhost/myApp as an additional valid callbackUrl is no an option in prod (?), so now I'm stuck on figuring out how to get a hold on the systemToken in this environment. 

I have a couple of questions about the background-logic/routines: 
Does the systemToken get created when a user approves the app, or is it created during the initial setup where you specify you need to use a systemuser for your logic? 
Would it be an idea to make this systemToken available 'somewhere' inside the admin-client?
Would it be possible to send this systemtoken with the other information (ClientId/Client secret)?

My scenario is a little strange, as most apps have a hostname they can register with the app, but in my specific case there is none. 

//Eivind

RE: Getting systemtoken without a valid callback url

Hi Eivind, I had a similar case just this week. Perhaps this can be helpful in your case as well.

In my case I needed to go from new Custom App, to a usable RefreshToken. The only callback I used was the default /login/final/CLIENT_ID.

As an example, let's say my ClientID is ABC123.

What I did was this:

1)

Open this in browser: https://online.superoffice.com/login/common/oauth/authorize?client_id=ABC123

Login, and get redirected to the /login/final/CLIENT_ID page. In the URL, notice that there is a CODE variable. Grab that.

2)

Open Postman and do a POST against /login/common/oauth/tokens where you pass in your settings and the code you got.

Actually, come to think of it, I made a CRMScript as well that did the final part. So you can choose if you want to do Postman or CRMScript :)

#setLanguageLevel 3;

String client_id = "ABC123";			//PUBLIC
String client_secret = "abcacbcabcacabacbacbabca";  //SECRET!
String code = "aabbccddeeff_code_from_url";
String redirect_uri = "https://online.superoffice.com/login/final/ABC123";
String grant_type = "authorization_code";

String url = "https://online.superoffice.com/login/common/oauth/tokens?client_id={client_id}&client_secret={client_secret}&code={code}&redirect_uri={redirect_uri}&grant_type={grant_type}";
url = url.substitute("{client_id}", client_id);
url = url.substitute("{client_secret}", client_secret);
url = url.substitute("{code}", code);
url = url.substitute("{redirect_uri}", redirect_uri);
url = url.substitute("{grant_type}", grant_type);

HTTP http;
http.setValue("", ""); //Required for POST
String result = String(http.post(url));
printLine(result);

You should get the token back from that. Hope that helps you.

Av: Frode Lillerud 13. des 2019

RE: Getting systemtoken without a valid callback url

Hello Frode, 

Thank you for the reply, the code-snippet will come in handy later on :) 

Unfortunately It doesn't return the systemToken, only an accessToken and refreshToken. 
I guess the systemToken is returned when i go here: 
https://online.superoffice.com/login/common/oauth/authorize?client_id=ABC123

So, when i use the code i can get the tokens i need to do stuff, but this would be on behalf of the logged in user and not the systemUser. 

The systemToken is normally stored in the application and used to exchange for a systemUser_ticket, so I dont really need a valid session for this step, only the systemToken itself

//Eivind




Av: Eivind Johan Fasting 13. des 2019

RE: Getting systemtoken without a valid callback url

Update on this: 

I figured out a method to use Postman to do this request for me. 
I filled it in like this: 

This returns basically the same 'stuff' as the crmscript above (access_token, refresh_token, token type and id_token). 
I still dont get the systemToken though, might be something fishy with my database? Could an explanation be that systemUser is not activated on this tenant (?)

I have tried X different methods now, and im able to get everything besides what i need.. 
Any suggestion is appreciated! :)  

//Eivind

Av: Eivind Johan Fasting 13. des 2019

RE: Getting systemtoken without a valid callback url

Hi Eivind,

There are a couple ways to solve this, which depend on the client type and format of the redirect url.

Is your app a native app or web app?

Finally, the system user token is in the id_token claims collection if you selected the "System user" context when registering the application. Remember to always validate the id_token.

EDIT: OK, just saw you said you were using a Console application...

A console application is a native application, and therefore should use the OpenID Connect Native App routine.

We have a console application that demonstrates the correct way to obtain the access/refresh/id tokens using this approach on Github. It depends on a certified client library IdentityModel.OidcClient

In that case, we can register your redirect URL as an expresstion, and then in the console source code you can specify any port your like:

^http://127.0.0.1\:\d{4,10}/desktop-callback$

The following demonstrates how to get the system user token, which can be added after the original lines:

//...

string netserverUrl = result.User.Claims.Where(c => c.Type.Contains("netserver_url")).Select(n => n.Value).FirstOrDefault();

string systemUserToken = result.User.Claims.Where(c => c.Type.Contains("system_token")).Select(n => n.Value).FirstOrDefault();

//...

Hope this help!

Av: Tony Yates 16. des 2019

RE: Getting systemtoken without a valid callback url

Hi, since it is in the id_token, you can get it by calling the /authorize endpoint with these parameters.

https://sod.superoffice.com/login/common/oauth/authorize?client_id=ABC123&response_type=id_token&scope=openid

And then you can grab the id_token from the URL it redirects to, and inspect it using www.jwt.io to see the system_token.

Tony, is it correct that the application needs to be configured to use a System Token, here, in order to get the system_token?

 

 

Av: Frode Lillerud 16. des 2019

RE: Getting systemtoken without a valid callback url

Please see my edits in the previous post. 

@Frode, yes, the system_user token is only included in the id_token JWT if that option was selected.

Please do not take shortcuts in production. Use certified clients for authentication that do validation, or implement the validation routines in your code. CRMScript will eventually support validating online JWTs. 

 

Av: Tony Yates 16. des 2019

RE: Getting systemtoken without a valid callback url

Hello, 

Tony: yes, that example is what i have been using (with some modifications). I got around this by adding http://localhost/ (thanks Margrethe!) as an additional whitelisted/valid callbackUrl, so i could specify that in the openIdConnect-code. 
That way i get the callback back to the listener i create, and i can get the systemToken from there. 

Frode: I will test that out later this week, but again i guess my scenario is rather 'spesific' and not something others might come across.

Again, thank you for the reply, it is much obliged :) 

EDIT: To mark this thread as 'solved' I check the last reply as the solution, for anyone reading this you should read the reponse from Frode and Tony above

//Eivind

Av: Eivind Johan Fasting 16. des 2019

RE: Getting systemtoken without a valid callback url

Using localhost for native apps is not recommended, to avoid inadvertently listening on network interfaces other than the loopback interface. Also is less susceptible to client-side firewalls and misconfigured host name resolution on the user's device. 

Best regards.

Av: Tony Yates 17. des 2019