Way to revert to auto-log in user without saving credentials separately?

Using ignition 8.1.47, Vision.

Have a active directory user source. We have auto logged in enaled with a service account, but people log in and out all the time with there personal accounts to do things. My logout button really should only revert back to the auto logged in user so that the HMI is still viewable. Right now the only way I see to do this is to hardcode my credentials in a script and do a system.security.switchUser. I know I can do other better ways of storing the credentials and if theres no better way I will do that, but what I am more curious about is if there is a easier built in way to “revert” back to the autologged in user with a system.* call?

No.

That said, I think we do keep track of the initial AuthenticationChallenge in memory and you could conceivably write a script to access this information, unpack it, and rinse that through a system function.
It'd be fragile, and guaranteed to break when you upgrade to 8.3, all that code changed.

Edit: Whoops, removed the perspective link as I missed the vision tag.

I came up with this ugliness that does work but I am more inclined to just keep the creds somewhere

from com.inductiveautomation.factorypmi.application.model.properties import LoginProps
from com.inductiveautomation.ignition.common.util import LoggerEx

def loginToAutoUser():
    log = LoggerEx.newBuilder().build("LoginPropReader")
    # Easieset way to get client context? lol prob not idk
    openWindow = system.gui.getOpenedWindowNames()[0]# I know at least one is open
    win - system.gui.getWindow(oepnWindow)
    context = win.getAppContext()
    project = context.getProject()
    loginProps = LoginProps.fromProjectResource(context, project, log)
    username = loginProps.getAutoLoginUsername()
    password = loginProps.getAutoLoginPassword()
    system.security.switchUser(username, password)

The above works but I don’t like not knowing exactly whats going on and if its safe. Maybe there’s a way to make the above not fragile and workable.

If not I’ll just put it somewhere and wait until a 8.3 for the secrets manager.

The pain point I am trying to address (which may be in 8.3) is keeping separate sets of credentials - one in the Vision project properties where I set the auto login information, and then the other file I am reading from to switch back to the auto login user.

I am using vision so this available for my situation.

You didn't hear this from me :smiley:

from com.inductiveautomation.factorypmi.application import FPMIApp
context = FPMIApp.getInstance().adapterContext

Your code there would actually still work in 8.3 :person_shrugging:

2 Likes

I'm going to have to look at implementing this. I've just been storing an encrypted version of the password so that it isn't stored in plain text (using the internal encryption methods used to store DB credentials and the like in Ignition already), but if I can pull the auto-login credentials automatically, that's much better.

1 Like

With @paul-griffith ‘s full blessing and backing

from com.inductiveautomation.factorypmi.application.model.properties import LoginProps
from com.inductiveautomation.ignition.common.util import LoggerEx
from com.inductiveautomation.factorypmi.application import FPMIApp

def loginToAutoUser():
    log = LoggerEx.newBuilder().build("LoginPropReader")
    context = FPMIApp.getInstance().adapterContext
    project = context.getProject()
    loginProps = LoginProps.fromProjectResource(context, project, log)
    username = loginProps.getAutoLoginUsername()
    password = loginProps.getAutoLoginPassword()
    system.security.switchUser(username, password)

Should log = LoggerEx.newBuilder.build() should be outside the function or better off inside? That I have no idea.

@michael.flagler yes I was trying to address that issue. Having two sources of these credentials is just one more thing that can get out of sync.

1 Like

Should be system.util.getLogger, and it's a micro-optimization but it would be "better" outside the function call.

The underlying objects are memoized under the hood so it's not really going to matter.

:wink:
Little known fact, every time you IgnitionGateway.get() you also get a file written to disk that has a phone number for the big red phone on my desk so you can bypass support.

2 Likes

Here's what I came up with plus an extra check to make sure we're not in designer (not sure if it would even work in designer):

from com.inductiveautomation.factorypmi.application.model.properties import LoginProps
from com.inductiveautomation.factorypmi.application import FPMIApp

logger = system.util.getLogger(system.util.getProjectName() + '.' + __name__)

def loginToAutoUser():
	# Get system flags for determining if this is designer or not
	flags = system.tag.readBlocking(['[System]Client/System/SystemFlags'])[0].value
	
	context = FPMIApp.getInstance().adapterContext
	project = context.getProject()
	loginProps = LoginProps.fromProjectResource(context, project, logger)
	
	username = loginProps.getAutoLoginUsername()
	password = loginProps.getAutoLoginPassword()
	
	# Only perform the switch user if we're not in designer
	if (flags & 1) == 0:
		system.security.switchUser(username, password)
	else:
		logger.infof('Not switching user to "%s" due to running in designer', username)

Edit: Looks like it may not be necessary, but at least prevents the error dialog.

2 Likes