Web Dev modern authentication

I want to use webdev to create an api to interface with some other systems.
I'm required to use OID or OAuth2.

Since the ignition webdev module only supports basic auth does anyone have experience with creating work arounds?
I could create a flask app to do the authentication and then re-POST to Ignition I guess but that is a lot of work.

If the others require OAuth2 etc. then wouldn't you just authenticate against them? As an example if you have a token system from an Azure Application you could go out and get the token and authenticate using that. You would need to have your secret be produced from somewhere in Ignition, but that is an option.

Maybe this is more of a simplistic answer, so please explain a little more on the use case and the authentication pattern. Are you wanting to have a user actually authenticate and pass back a token that identifies them and their permissions (JWT of some sort essentially) or is a headless authentication pattern.

Maybe I am misunderstanding and you want the APIs to actually pull data from Ignition?

Benjamin,

I probably didn't explain it clearly but yes your last point is correct.
We want to ingest data from another (internal) party. The standard way would be that we setup an API where they can POST.
A requirement from infosec is to use modern authentication, so Oauth2.
We're the API Server, they're the client POST-ing.

The reverse scenario is also present in our environment and there we basically do what you mentioned. We use a secret to request a bearer token that we then use to authenticate to the API.

Well I could see a few options:

1.) You could lean into the Ignition Authentication and make sure that the IdP that you are using is an OIDC (This will be username password unfortunately, but will use the OIDC for the IdP)

2.) You could do what you recommended and include the secret in the request to ignition and actually have Ignition go grab another token and verify against an endpoint that is has the valid permissions. I would utilize something like AWS or Azure secret managers and authenticate against those.

Please use https

the latter Feels a bit convoluted so I would be interested to see what others recommend and use but overall, it would be nice if there was some more native way to do this, but that would require secret management inside of Ignition.

@PGriffith had a proof-of-concept module at one point I believe, but I am not sure it is intended for production or just a PoC.

Edit:
I found the module repo:

paul-griffith/secret-keeper: Toy, incomplete Ignition proof-of-concept module to store secrets in the IDB

Absolutely not suitable for production. We've got a better way to manage and secure secrets in 8.3, and while I don't think everything's wired up to make it easy to consume from scripting yet, it's definitely on the roadmap.

2 Likes

We currently put secrets in env variables and plan to migrate to the 8.3 solution when its released.

But @Benjamin_Furlani I think you're not getting what I mean.

The players and data flow looks like this:

  • App-A has the data we want
  • Our Ignition installation has an API programmed in the webdev module that can receive a POST with the data in the body. We then put the data in tags/db/...
  • We have an OAuth2 authorization server

The data flow is like this:

  • App-A requests a bearer token to the Auth server
  • App-A uses this bearer token in its Post to our Ignition server
  • Our Ignition server should extract, decode, verify and validate this token

In this last step a feasible option I think is to have an application running, seperate from ignition that handles the authentication step and validates. If its correct then this intermediate/proxy app can do the POST to ignition itself.
Alternatively we do the extract, decode, verify and validate steps in ignition jython code itself

But I'm not sure that coding this in Ignition is a possible or a good idea.
Ideally Inductive automation would work on a native implementation of Oauth2 for webdev ofcourse..

In this dataflow, only App-A has secrets, the Ignition server does not, it only needs to validate the token with the auth servers public key.

@PGriffith Advice would be greatly appreciated :slight_smile:

Ah, I see what you are saying now.

You could decode the JWT right there in the webdev when you receive the post:

This doesn't verify the signature but could be a starting point. You would obviously need code to actually do the verification of what you are looking for in the actual JWT.

import base64
import json

def decodeBase64(inputStr):
	missingPadding = 4 - (len(inputStr) % 4)
	if missingPadding :
		inputStr += '=' * missingPadding 
	return base64.urlsafe_b64decode(inputStr)

def decodeJWT(token):
	try:
		b64Header, b64Payload, b64Signature = token.split('.')
		header = json.loads(decodeBase64(b64Header))
		payload = json.loads(decodeBase64(b64Payload))

		return {
			'header': header,
			'payload': payload,
			'signature': b64Signature
		}
	except Exception as e:
		return {"error": str(e)}

Yeah this is what I mean.

The difficulty is probably the decryption in ignition, I'd need to find a jython lib to handle rsa decryption.

Something to investigate tomorrow :slight_smile:

1 Like

Yeah, sounds like fun haha.

Sorry for the initial confusion! Hope this at least pushes you in the right direction. Please let us know what your solution ends up being when you figure it out.

Don't use a Jython lib, use a standard Java library and just call it from Jython. Much better for your sanity and future maintenance.

4 Likes

Thanks for the tip.

Are there any limitations on what kind of java lib is compatible?

You can't replace anything Ignition ships with. Which is a huge number of resources on top of the java standard libraries. Browse through your gateway install folder for a preview of the things you can simple import in Ignition.