Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

UA Authentication

More
09 Nov 2023 15:31 #12343 by support
Replied by support on topic UA Authentication
Hello.

Please create a new topic thread next time, for any new issue. You can always put inside a link to some other post, if there is a relationship. In this case, you have added to a forum thread that is not actually related, making the forums look more confusing to the user.

I know where your problem comes from.

First, you can remove the parts of your code that set the UserInfo, UserName and/or Password on the $EndpointDescriptor directly. The correct part is the one with $EndpointDescriptor->UserIdentity.

Then, the actual problem lies in the usage of the CallMethod method, and the $EndpointDescriptor->ToString() as its first argument. What happens there is that $EndpointDescriptor->ToString() does not represent all contents of the endpoint descriptor - so by converting it to string, the user identity gets lost.

But if course you HAVE to use a string for the endpoint descriptor with the CallMethod call in COM (PHP). This is because COM does not have method overloads. In .NET we have an overload that has the actual UAEndpointDescriptor object as the first argument - as well as many other overloads. In COM we have chosen the most simplest case as the overload to expose.

We still allow the operation to made in COM as well - but you need to switch from the simplest method (which is CallMethod) to the other method that is the "most complicated" one: In this case, CallMultipleMethods.

So, even though you are calling just one method, in COM (PHP) you need to rewrite your code to use CallMultipleMethods, with one method. The CallMultipleMethods accept an array of arguments, each describing one method call. The array element then contains the full UAEndpointDescriptor object, so you can fill it in correctly, including its UserIdentity.

Unfortunately we do not have the PHP example with CallMultipleMethods currently available, but you should be available to construct it using that example in other programming languages, here: opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...Call%20multiple%20methods.html .


I hope this helps.

Best regards

Please Log in or Create an account to join the conversation.

More
09 Nov 2023 14:57 #12342 by m.spinsanti@swoa.it
Up to now we have profitably used your library to implement numerous integrations between our management software and customers' machine tools.

We have never needed to activate the connection with user/password but now we find ourselves in the situation of needing it to be able to use the CALL function of a method that is inhibited for anonymous connection (in the below example you’ll find all the authenticated access modes we tested, even individually).

Let's start by saying that, on this same machine, we are already collecting data from an anonymous connection.
Below we attach the used code and runtime screenshots showing reported errors.

Can you give us some suggestions to unravel the problem?


PHP SOURCE CODE
<?php
$bDebug = true;
if ($bDebug)
error_reporting(E_ALL);

$EndpointDescriptor = new COM("OpcLabs.EasyOpc.UA.UAEndpointDescriptor");
$EndpointDescriptor->UrlString = "opc.tcp://192.168.10.20:51210/UA/E77Server";

//com_print_typeinfo($EndpointDescriptor->UserIdentity->AnonymousTokenInfo);
$EndpointDescriptor->UserInfo = "KM:km";

$EndpointDescriptor->UserName = "KM";
$EndpointDescriptor->Password = "km";

$EndpointDescriptor->UserIdentity->AnonymousTokenInfo->IsEnabled = false;
$EndpointDescriptor->UserIdentity->UserNameTokenInfo->UserName = "KM";
$EndpointDescriptor->UserIdentity->UserNameTokenInfo->Password = "km";
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");

// This example shows how to call a single method, and pass arguments to and from it.
$inputs[0] = "a";
$inputs[1] = "b";
$inputs[2] = "c";
$inputs[3] = "d";
$inputs[4] = "e";
$inputs[5] = "f";
$inputs[6] = 2;
$inputs[7] = "";
$inputs[8] = "";
$inputs[9] = "";
$inputs[10] = true;
$inputs[11] = 3;
$inputs[12] = 0;
$inputs[13] = 0.0;

$typeCodes[0] = 18; // TypeCode.String
$typeCodes[1] = 18; // TypeCode.String
$typeCodes[2] = 18; // TypeCode.String
$typeCodes[3] = 18; // TypeCode.String
$typeCodes[4] = 18; // TypeCode.String
$typeCodes[5] = 18; // TypeCode.String
$typeCodes[6] = 10; // TypeCode.UInt32
$typeCodes[7] = 18; // TypeCode.String
$typeCodes[8] = 18; // TypeCode.String
$typeCodes[9] = 18; // TypeCode.String
$typeCodes[10] = 3; // TypeCode.Boolean
$typeCodes[11] = 12; // TypeCode.UInt64
$typeCodes[12] = 12; // TypeCode.UInt64
$typeCodes[13] = 14; // TypeCode.UInt64

// Perform the operation
try
{
$outputs = $Client->CallMethod(
$EndpointDescriptor->ToString(),
"nsu=http://www.euromap.org/euromap77/ ;ns=4;s=70250", // Node descriptor
"nsu=http://www.euromap.org/euromap77/ ;ns=4;s=70250", // Method Node Id
$inputs,
$typeCodes);
}

catch (com_exception $e)
{
printf("*** Failure: %s\n", $e->getMessage());
exit();
}

// Display results
for ($i = 0; $i < count($outputs); $i++)
{
printf("outputs[d]s\n", $i, $outputs[$i]);
}
unset($Client);
exit();
?>
Attachments:

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 13:10 #9779 by escarre
Replied by escarre on topic UA Authentication
Hello,

Of course.

Code to send User and Password, acceptint de certificate:
EasyUAClientConfiguration := TEasyUAClientConfiguration.Create(nil);
    UserIdentity := TUserIdentity.Create(nil);
    try
      UserIdentity.UserNameTokenInfo.UserName := ParamStr2;
      Useridentity.UserNameTokenInfo.Password := ParamStr3;
      EasyUAClientConfiguration.AdaptableParameters.SessionParameters.UserIdentity := Useridentity.DefaultInterface;
      EasyUAClientConfiguration.RemoteMachineName := ParamStr1;
      EasyUAClientConfiguration.AdaptableParameters.SessionParameters.EndpointSelectionPolicy.AllowedMessageSecurityModes := UAMessageSecurityModes_All;
      EasyUAClientConfiguration.SharedParameters.EngineParameters.CertificateAcceptancePolicy.AcceptAnyCertificate := True;
      EasyUAClientConfiguration.Connect;
    finally
      UserIdentity.Free;
      EasyUAClientConfiguration.Free;
    end;

For each value I need to read:
ReadArgument := CoUAReadArguments.Create;
        ReadArgument.EndpointDescriptor.UrlString := strOPCServer;
        ReadArgument.NodeDescriptor.NodeId.ExpandedText := NodeId + OPCItem;
        ReadArgument.AttributeId := UAAttributeId_DataType;

The code to Read the items:
TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(ClienteOPCUA.ReadMultipleValues(PSafeArray(TVarData(Arguments).VArray)));
  for intVariable := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
    Result := IInterface(Results[intVariable]) as _ValueResult;
    if VarIsEmpty(Result.Value) then
      SaveError('Value.Value: ' + strIdVariableEscribir + ' - ' + ID_NO_EXISTE)
    else
    begin
      SaveValue(strIdVariableEscribir , Result.Value);
    end;
  end;

Thanks for you help!
Escarre
The following user(s) said Thank You: support

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 12:52 #9778 by support
Replied by support on topic UA Authentication
OK, that was a quick sequence of posts, and I was not present. I am glad you got it working. I suggest that you post here what were the causes of your problems, so that other users can learn from it.

The proper and secure way to get rid of the certificate validation dialog is to copy the server's certificate to the "trusted peers" certificate store. More information: opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...%20Instance%20Certificate.html .

Most likely this means you should inspect the certificates you have under "C:\ProgramData\OPC Foundation\CertificateStores\RejectedCertificates\certs", locate the one you want to trust, and copy it over to "C:\ProgramData\OPC Foundation\CertificateStores\UA Applications\certs". Alternatively, there should also be a (server-specific) way to obtain the server's certificate on the server side directly (without it having to be first transferred to the client and initially rejected).

This will have to be repeated on every machine where the client app will run (and, if it is connecting to different server instances, the server certificates will then of course be different).

There are also insecure ways - not recommended.

Best regards

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 10:45 #9776 by escarre
Replied by escarre on topic UA Authentication
Hello,

Finally I can read the data. When the application initiates, this form appears:



Can I avoid this form?

Thanks a lot,
Escarre
Attachments:

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 09:38 #9775 by escarre
Replied by escarre on topic UA Authentication
Hello,

I have attatched the node I want to read.

Thanks,
Escarre

Attachments:

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 09:17 #9774 by escarre
Replied by escarre on topic UA Authentication
Hi,

I made another test, using OnDataChangeNotification.

When I receive the event, the eventArgs.Arguments.NodeDescriptor.DisplayString value NodeId="ns=3;s=_System.General.Temperature"
But eventArgs.AttributeData is nil.

Thanks again,
Escarre

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 08:56 #9773 by escarre
Replied by escarre on topic UA Authentication
Hi again,

When I want to display results an exception raises: EIntFCastError Interface not supported
But if I use this code (Result is a _ValueResult variable):
Result := IInterface(Results[intVariable]) as _ValueResult
there are no error, but the Result.value is unassigned.

This code in another OPC server works properly, so I don't know why is not working.

Thanks,
Escarre

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 07:21 #9769 by support
Replied by support on topic UA Authentication
Hello.

Reading a list of OPC UA items:
// This example shows how to read the attributes of 4 OPC-UA nodes at once, and
// display the results.
 
class procedure ReadMultiple.Main;
var
  Arguments: OleVariant;
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  I: Cardinal;
  ReadArguments1, ReadArguments2, ReadArguments3, ReadArguments4: _UAReadArguments;
  Result: _UAAttributeDataResult;
  Results: OleVariant;
begin
  ReadArguments1 := CoUAReadArguments.Create;
  ReadArguments1.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  ReadArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10853';
 
  ReadArguments2 := CoUAReadArguments.Create;
  ReadArguments2.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  ReadArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10845';
 
  ReadArguments3 := CoUAReadArguments.Create;
  ReadArguments3.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  ReadArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10304';
 
  ReadArguments4 := CoUAReadArguments.Create;
  ReadArguments4.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  ReadArguments4.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10389';
 
  Arguments := VarArrayCreate([0, 3], varVariant);
  Arguments[0] := ReadArguments1;
  Arguments[1] := ReadArguments2;
  Arguments[2] := ReadArguments3;
  Arguments[3] := ReadArguments4;
 
  // Instantiate the client object
  Client := CoEasyUAClient.Create;
 
  // Perform the operation
  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(Client.ReadMultiple(Arguments));
 
  // Display results
  for I := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
    Result := IInterface(Results[I]) as _UAAttributeDataResult;
    if Result.Succeeded then
      WriteLn('results(', I, ').AttributeData: ', Result.AttributeData.ToString)
    else
      WriteLn('results(', I, ') *** Failure: ', Result.ErrorMessageBrief);
  end;
end;

Setting username and password: At the beginning of opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...ck%20certificate%20status.html

(always switch to the "Object Pascal" example tab)

So you just need to combine parts of these two examples together.
Best regards

Please Log in or Create an account to join the conversation.

More
17 Jun 2021 06:36 #9767 by escarre
Replied by escarre on topic UA Authentication
Hello,

I need to set the user and password and read a list of OPC items.
What is the best way to get these data list?

Are there any example in Delphi?

Thanks,
Escarre

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.079 seconds