# Perspective changing value of control before authenticating the user

**URL:** <https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [October 12, 2022, 2:24pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117 "2022-10-12T14:24:24Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daniel\_M](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_M](https://forum.inductiveautomation.com/u/Daniel_M)\
**Post date:** [October 12, 2022, 2:24pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/1 "2022-10-12T14:24:24Z")

</div>

I need to have a specification where the Perspective interface needs to authenticate the user (prompt for username and password) on each user input (toggling buttons and moving sliders, etc).

I currently have that configured in the event configuration for each input as an Auth Challenge for an onClick mouse event.

When I tested it out however, the input would change the tag value, and then authenticate the user. This is the opposite sequence of what I need to happen.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [October 12, 2022, 3:08pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/2 "2022-10-12T15:08:28Z")

</div>

Show the code, man! Show the code!  
Don't forget to use the \</\> code formatting button!

---

<div class="post-metadata">

**Author:** ![Daniel\_M](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_M](https://forum.inductiveautomation.com/u/Daniel_M)\
**Post date:** [October 12, 2022, 3:20pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/3 "2022-10-12T15:20:14Z")

</div>

I don't really have any code. I just have these settings. Is there code I'm missing that I need to add?

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/7/97d3e87f73712f198ee433e8d5d42ecdbe02ff5b.png)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 12, 2022, 4:25pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/4 "2022-10-12T16:25:57Z")

</div>

What you're expecting just isn't how the authentication challenge works.

We don't currently have a way to automatically restrict every component to require an auth challenge.  
What you'd have to do is use scripting as a middleman:

- Add a property change script to the 'value' property on each component. When it's changed on one of your components (which will have to be bound **unidirectionally** to your tags), you can invoke [`system.perspective.authenticationChallenge`](https://docs.inductiveautomation.com/display/DOC81/system.perspective.authenticationChallenge) with a well-structured `payload` dictionary.
- In the [Authentication Challenge Completed](https://docs.inductiveautomation.com/display/DOC81/Perspective+Session+Event+Scripts#PerspectiveSessionEventScripts-AuthenticationChallengeCompleted) event script, you would parse out the payload (which should probably include a tagPath and a value) and then programmatically issue a write with `system.tag.writeBlocking`.

This may seem overwrought at first glance, but is a requirement because of the asynchronous nature of identity providers.

---

<div class="post-metadata">

**Author:** ![Daniel\_M](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_M](https://forum.inductiveautomation.com/u/Daniel_M)\
**Post date:** [October 12, 2022, 5:12pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/5 "2022-10-12T17:12:44Z")

</div>

Apologies in advance for my horrible code. I'm still a beginner with Ignition and this is my first time hearing about payloads. Would the code look something like this?

Property change script on toggle switch:

```auto
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
	payload = {'newVal':currentValue, 'tagPath':origin}
	system.perspective.authenticationChallenge(payload)

```

Session Events:

```auto
def onAuthChallengeCompleted(session, payload, result):
	val = payload['newVal']
	tagPath = payload['tagPath']
	system.tag.writeBlocking(tagPath, val)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 12, 2022, 5:26pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/6 "2022-10-12T17:26:37Z")

</div>

That code looks perfect, actually, with one hiccup - you can't use `origin` like that; it's going to be a value like "Browser" or "Binding" or "Session", not a useful tagpath.

You can't dynamically retrieve the tagpath _from_ a binding, but what you can do is add a custom property to your (in this case, toggle switch) that's just the tag path you care about as a string.  
Then you can switch your unidirectional binding to be an "Indirect" binding and reference that custom property. Then update your property change script to also refer to that custom property (e.g. `self.custom.tagPath` or whatever you end up naming it).

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 12, 2022, 5:35pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/7 "2022-10-12T17:35:04Z")

</div>

Don't forget to check for a successful result before writing....

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 12, 2022, 5:47pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/8 "2022-10-12T17:47:23Z")

</div>

Hah, yeah, good catch.  
You'll want to put an `if result.isSuccess():` before initiating a write.

---

<div class="post-metadata">

**Author:** ![Daniel\_M](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_M](https://forum.inductiveautomation.com/u/Daniel_M)\
**Post date:** [October 12, 2022, 7:10pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/10 "2022-10-12T19:10:05Z")

</div>

Updates to the code:

- Added a custom property tagPath = "[default]New Tag" (temporary tag for the proof of concept).

Property change script:

```auto
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
	payload = {'newVal':currentValue, 'tagPath':self.custom.tagPath}
	system.perspective.authenticationChallenge(payload)

```

Session Event

```auto
def onAuthChallengeCompleted(session, payload, result):
	val = payload['newVal']
	tagPath = payload['tagPath']
	if result.isSuccess():
		system.tag.writeBlocking(tagPath, val)

```

So that doesn't work. I get the following error:

> Error running property change script on ToggleSwitch.props.selected: Traceback (most recent call last): File "function:valueChanged", line 3, in valueChanged at java.base/java.util.UUID.fromString(Unknown Source) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.getSession(AbstractScriptingFunctions.java:91) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:118) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.authenticationChallenge(PerspectiveScriptingFunctions.java:418) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: UUID string too large

And there's no other way to do this? It would have to be done for several hundred tags and controls.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 12, 2022, 7:19pm UTC](https://forum.inductiveautomation.com/t/perspective-changing-value-of-control-before-authenticating-the-user/65117/11 "2022-10-12T19:19:41Z")

</div>

Try `system.perspective.authenticationChallenge(payload=payload)`. I think the function is confused about which argument you're passing in.

> [@Daniel\_M](#):
>
> And there's no other way to do this?

Fundamentally, not really. One thing you _could_ do is make repeatable views that contain this additional logic for you. You can have an input parameter `tagPath`, and then the component you want to wrap inside. Then you just drop your wrapping view into your main screen and configure the tag paths accordingly. This does have some performance ramifications, though; embedded views can get expensive on complicated screens.

It may be worth seeing if the specification can be amended to allow you to require an authentication challenge to open a write-able version of your screens, or otherwise enable editing on all the components. If the spec truly requires that _every operation_ pass an auth challenge, with no grace period whatsoever, this is your only option (to my knowledge, anyways).
