sciortid opened a new issue, #1844:
URL: https://github.com/apache/plc4x/issues/1844

   ### What would you like to happen?
   
   Hello! First of all I'm pretty sure I'm missing something but i'll try.
   
   I created an OPCUA Python server with username or certificates 
authentication policies. It has been tested with OPCUA Expert and i can access 
it with both policies methods.
   
   I (and ChatGPT) created a simple standalone example to connect to the server:
   ```
   package opcua;
   import org.apache.plc4x.java.api.PlcConnection;
   import org.apache.plc4x.java.api.messages.PlcReadRequest;
   import org.apache.plc4x.java.api.messages.PlcReadResponse;
   import org.apache.plc4x.java.DefaultPlcDriverManager;
   
   import java.util.concurrent.CompletableFuture;
   
   public class OpcUaClientWithCert {
   
       public static void main(String[] args) {
           // URL del server OPC UA, con certificato client e chiave privata 
inclusi
           String serverUrl = "opcua:tcp://127.0.0.1:4840";
           String discovery = "true";
           String securityPolicy = "Basic256Sha256";  // Percorso del 
certificato del client
           String clientKeyStore = ".../client_keystore.p12";
           String clientKeySotrePass = "clientKeystorePassword";         // 
Password della chiave
   
           // Modificare la stringa di connessione per includere certificato e 
chiave privata
           String connectionString = String.format(
                   
"%s?discovery=%s&security-policy=%s&key-store-file=%s&key-store-password=%s",
                   serverUrl, discovery, securityPolicy, clientKeyStore, 
clientKeySotrePass
           );
   
           String nodeId = "ns=2;i=2";  // Sostituire con il nodo che si 
desidera leggere
   
           // Connettersi al server OPC UA con certificati
           DefaultPlcDriverManager driverManager = new 
DefaultPlcDriverManager(); // Crea un'istanza di DefaultPlcDriverManager
                try (PlcConnection connection = 
driverManager.getConnection(connectionString)) {
               if (connection != null && connection.isConnected()) {
                   System.out.println("Connessione stabilita con il server OPC 
UA usando certificati.");
   
                   // Creare una richiesta di lettura
                   PlcReadRequest.Builder builder = 
connection.readRequestBuilder();
                   builder.addTagAddress("myNode", nodeId);  // Aggiungere il 
nodo da leggere
   
                   PlcReadRequest readRequest = builder.build();
   
                   // Eseguire la lettura in modo asincrono
                   CompletableFuture<? extends PlcReadResponse> future = 
readRequest.execute();
                   PlcReadResponse response = future.get();
   
                   // Stampare il risultato
                   System.out.println("Valore letto dal nodo: " + 
response.getObject("myNode"));
               } else {
                   System.out.println("Connessione fallita.");
               }
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
   }
   
   ```
   
   And this is the pom.xml file:
   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd";>
     
     <modelVersion>4.0.0</modelVersion>
     <groupId>test</groupId>
     <artifactId>opcua</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>test</name>
     <description>test</description>
     
        <dependencies>
        
                <dependency>
                                <groupId>org.apache.plc4x</groupId>
                                <artifactId>plc4j-api</artifactId>
                                <version>0.12.0</version>
                </dependency>
                
                <dependency>
                          <groupId>org.apache.plc4x</groupId>
                          <artifactId>plc4j-driver-opcua</artifactId>
                          <version>0.12.0</version>
                </dependency>
                
                <dependency>
                            <groupId>org.apache.plc4x</groupId>
                            <artifactId>plc4j-transport-tcp</artifactId>
                            <version>0.12.0</version>
                </dependency>
                
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.36</version> 
            </dependency>
            
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-simple</artifactId>
                <version>1.7.36</version>
            </dependency>
   
        </dependencies>
   </project>
   ```
   
   When it runs, I get the "_Unable to find endpoint.._" exception in this part 
of _SecureChannel.java_
   ```
       private void selectEndpoint(CreateSessionResponse sessionResponse) 
throws PlcRuntimeException {
           // Get a list of the endpoints which match ours.
           Stream<EndpointDescription> filteredEndpoints = 
sessionResponse.getServerEndpoints().stream()
               .map(e -> (EndpointDescription) e)
               .filter(this::isEndpoint);
   
           //Determine if the requested security policy is included in the 
endpoint
           filteredEndpoints.forEach(endpoint -> hasIdentity(
               endpoint.getUserIdentityTokens().stream()
                   .map(p -> (UserTokenPolicy) p)
                   .toArray(UserTokenPolicy[]::new)
           ));
   
           if (this.policyId == null) {
               throw new PlcRuntimeException("Unable to find endpoint - " + 
this.endpoints.get(0));
           }
           if (this.tokenType == null) {
               throw new PlcRuntimeException("Unable to find Security Policy 
for endpoint - " + this.endpoints.get(0));
           }
       }
   ```
   
   
   And noticed this is because the policyId is set to null but because 
**apparently the _hasIdentity_ function has no option for policy other than 
anonymous and username**:
   ```
       private void hasIdentity(UserTokenPolicy[] policies) {
           for (UserTokenPolicy identityToken : policies) {
               if ((identityToken.getTokenType() == 
UserTokenType.userTokenTypeAnonymous) && (this.username == null)) {
                   policyId = identityToken.getPolicyId();
                   tokenType = identityToken.getTokenType();
               } else if ((identityToken.getTokenType() == 
UserTokenType.userTokenTypeUserName) && (this.username != null)) {
                   policyId = identityToken.getPolicyId();
                   tokenType = identityToken.getTokenType();
               }
           }
       }
   ```
   
   The policies that my server returns correspond to the ones i set with the 
python script:
   
   
![image](https://github.com/user-attachments/assets/3f8d3f01-75df-4469-b082-9c4f66c1d69e)
   
![image](https://github.com/user-attachments/assets/2570905a-d1e0-4024-9112-dd76804b079a)
   
   What am I missing? Shouldn't the library allow this kind of access with just 
the cetificate? I expected other "if" for certificate policies. Did i end up in 
other functions that should not be used for this policies? In this case, is 
there something wrong with the main function? 
   
   Please note that the example works if i modify the connection string by just 
adding the username & password, correctly reading the node value:
   
    ```
          String serverUrl = "opcua:tcp://127.0.0.1:4840";
           String discovery = "true";
           String securityPolicy = "Basic256Sha256";  // Percorso del 
certificato del client
           String clientKeyStore = "..../client_keystore.p12";
           String clientKeySotrePass = "clientKeystorePassword";         // 
Password della chiave
           String userName = "user1";
           String password = "password1";
           // Modificare la stringa di connessione per includere certificato e 
chiave privata
           String connectionString = String.format(
                   
"%s?discovery=%s&security-policy=%s&key-store-file=%s&key-store-password=%s&username=%s&password=%s",
                   serverUrl, discovery, securityPolicy, clientKeyStore, 
clientKeySotrePass, userName, password
           );
   ```
   
   But it does not surprise me  because it is using the username policy in this 
case (even if Basic256Sha256 is still specified)
   
   ### Programming Languages
   
   - [X] plc4j
   - [ ] plc4go
   - [ ] plc4c
   - [ ] plc4net
   
   ### Protocols
   
   - [ ] AB-Ethernet
   - [ ] ADS /AMS
   - [ ] BACnet/IP
   - [ ] CANopen
   - [ ] DeltaV
   - [ ] DF1
   - [ ] EtherNet/IP
   - [ ] Firmata
   - [ ] KNXnet/IP
   - [ ] Modbus
   - [X] OPC-UA
   - [ ] S7


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to