Solved

Authentication method Indicium (Universal) for external applications

  • 2 September 2021
  • 10 replies
  • 496 views

Userlevel 5
Badge +20

Together with a fellow developer, I am looking for a way to connect to Indicium (Universal) as efficiently and securely as possible from an external application.

I couldn't find anything about this in the documentation and in the community.

From the data traffic I have been able to deduce that the Universal GUI uses Basic/Cookie Authentication. We could use this way, but probably there is a better way.

According to others, there are better alternatives such as JSON Web Tokens (JWT), instead of cookie authentication. I don't know what more the Indicium API offers in terms of authentication.

I'm looking for best practice examples.

Is there anyone who has already looked into this and can give advise?

icon

Best answer by Vincent Doppenberg 15 September 2021, 13:44

View original

10 replies

Userlevel 1
Badge +2

Hi @Harm Horstman, @Barry,

Wealready started a project with harmonizer.cloud. Barry and @Anne Buit are involved.

Question for @Barry is it possible to add or connect Harm in our current API and documentation project?

Userlevel 7
Badge +5

Hi all,

OAuth2 is probably the way to go to allow external applications to use Indicium on behalf of a user or service account.

You can find information on how to configure this here:

 

Userlevel 5
Badge +20

Sorry, but with the currently available information/documentation is not enough to figure out how to set up a scenario with OAuth2 authentication. 

Can someone give a step-by-step explanation, with screenshots, on how to enable OAuth2 authentication in IAM and establish a secure connection from a third party platform or application with Indicium. Without the need of re-entering credentials every hour?

 

Userlevel 6
Badge +4

Hello Harm,

It’s difficult to give a step-by-step explanation on how to set up OAuth 2.0 authentication when most of this depends on the third party platform that you’re trying to connect to Indicium. I will explain how to configure an OpenID client in IAM and how the HTTP requests of the authentication flow work, but I don’t have enough information to give a more tailored explanation than that.

You start by creating an OpenID client in IAM with the Enabled checkbox checked. If you want access to Indicium’s API then the API checkbox must be checked. If you want to be able to refresh your access token without re-entering credentials, then the Offline checkbox must be checked. I don’t expect other checkboxes to be important in your case since you’re only looking to authenticate a third party to use Indicium’s API.

 

After creating the OpenID client in IAM, go to the Configuration detail and add a Redirect URI. The redirect URI is the URI you want to end up at after the authentication flow. Typically you’ll want to return to the client application that started the authentication flow.

 

Also add a Client secret, one that is a bit more secure than the one in my screenshot. It can be a value of your choice, but treat it like a password.

 

This is the minimum configuration necessary in order to use OAuth 2.0 from a third party platform. Please note that every change to any of these OpenID settings in IAM will require Indicium to be restarted. From this point onwards Indicium will simply accept the standard OAuth 2.0 Authentication Code requests in order to obtain an access_token and a refresh_token.

The HTTP requests for the Authentication Code flow work as described below.

You start with the Authorization Code request. This request will give you a code for a specific OpenID client and a set of scopes. Which scopes can be requested depends on the checkboxes that are checked in the OpenID client configuration in IAM. In your case you’ll want the scopes openid and offline_access. The values for the client_id and redirect_uri parameters also depend on the values you’ve entered into IAM in the steps above.

GET
<indicium_base_uri>/connect/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:5000/&scope=openid offline_access

This request will lead to Indicium’s login page where a user needs to log in and, if necessary, give consent for their user information being accessed by a third party. This only needs to be done once. After doing this, you will be redirected to the provided redirect_uri and Indicium will add a code parameter to the query string of the redirect URI. With my settings in this example, Indicium would redirect to the following URI:

http://localhost:5000/?code=XXX&scope=openid offline_access&session_state=YYY

The XXX value is important for the following request.

Next is the Token request. Here you’ll exchange the receibved authorization code and the client secret for an access_token and a refresh_token. For my example, the request will look like this:

 

The response will be a JSON object containing an access_token property and a refresh_token property. The access token is a JWT token that can be used to authenticate a user with, using the Bearer authentication scheme.

In a client like Insomnia that would simply look like this:

 

But it translates to the following HTTP request header:

Authorization: Bearer XXX

Very similar to how Basic authentication works.

 

The access token is only valid for one hour, but this is where the refresh token comes in. Once a expired, a new access token can be obtained by exchanging the refresh token. Note that the refresh token can only be used once, but during the exchange you will also obtain a new refresh token.

So finally we have the Refresh Token request. This request is very similar to the previous token request, but the grant_type parameter must have the value refresh_token and instead of the code parameter, you’ll need to provide a refresh_token parameter.

 

The response of this request is the same as the previous token request.

I hope this helps with understanding how to set up OAuth 2.0 authentication with Indicium.

Userlevel 5
Badge +20

Hi Vincent, 

Thank you very much. This looks very clear to me.

I'll will keep you posted on further developments.

 

 

Userlevel 1
Badge +2

After reading this answer I was enthusiastic and want to give it a try again. I read @Anne Buit @Jasper blogposts and more even back to the Indicium Docs. Unfortunately I ran into a DotNet error after adding the Open ID settings and { "BearerTokenAuthority" : "https://<URL>:5001" } 

I discussed this with @Barry earlier and let's say I’m a "power user", @barry infrastructure expert and you are the software expert. I understand an API is custom build with partners URL etc but there must be a way to a “central Docs” instead of blog posts en Q&A? Create a step-by-step installation guide with a simple API from ThinkWiseSoftware.com to verify the basic “Open ID installation” on TSF customer installation. I will help, of course, with time and resources if needed.  

Now I'm stuck again with a lot of questions about it. Is it a configuration error? OpenID settings error? Typo? IAM? appsettings.config indicium? Security issue? Even a missed installation step is possible :-(

Userlevel 6
Badge +4

Hello Jaap,

We are working on making our documentation more centralized and accessible. It's true that it can be easy to lose track of blog posts and answers to questions on the community.

As for your specific issue, the https://localhost:5001 URL for the BearerTokenAuthority configuration is just an example URL of where an Indicium might be located. It should be the URL that takes you to Indicium's landing page. In your case it is unlikely that you need the :5001 port in there.

I hope this helps.

Userlevel 5

When adding a openIDclient and restarting the indicium, I got an error while starting.

In the end the issue was that the load user profile was set on false.
Just in case someone else is experiencing the same problem. 

AppPool -> advanced settings _> load user profile → true 

Userlevel 2
Badge +1

We are currently running into issues using cookie authentication within our application.

After coming across this post, it seems this could work, but one thing seems unclear, so perhaps a follow-up:

The answer to this question reads as though these OAuth JWT tokens are client based (so we would be authenticating the application itself as a client with Indicium), however we require authentication for specific users within the Thinkwise application.

Therefore our question is; are these JWTs specific to a user, or are they only for authenticating a client?

Userlevel 6
Badge +4

Hello Jeroen,

The answer is actually both.

When using the Authorization Code flow, the access tokens are user-specific authentication tokens that allow API access as that user (given that the API access checkbox is checked in IAM). When API calls are made using these access tokens, the dbo.tsf_user() function on the database will also return the expected username.

The reason it seems like the authentication is client-based is because it is also client-based. Only valid (i.e. registered Client Applications in IAM) clients can request access tokens for users, using the Authorization Code flow. For this, the client_id and client_secret are used. After providing a valid client_id and client_secret, the login screen will be shown to the user, followed by a consent screen in which the user consents to giving certain access on behalf of the user to the client.

 

When using the Client Credentials flow, a pure client-based authentication mode is used without an intervening login and consent screen for a user (i.e. the authentication is only based on client_id and client_secret). In IAM, the Client Application must have a user linked to it and this is the ‘user’ that will be represented by the access token. This is a simple way to apply our role-based access control to this type of authentication as well.

 

In the near future, we will make the client_secret optional when using the Authorization Code flow. This would allow for so-called public clients to obtain access tokens for users without authenticating themselves as a registered client via the client_secret. This does not add any extra functionality since you could also use a publicly known client_secret, but it is a better practice to omit the client_secret entirely if the client application cannot safely store it (e.g. a pure Javascript client application).

I hope this clarifies some things.

Reply