18
18
*/
19
19
package org .apache .plc4x .java .opcua .context ;
20
20
21
+ import static java .util .Map .entry ;
21
22
import static java .util .concurrent .Executors .newSingleThreadScheduledExecutor ;
22
23
import static org .apache .plc4x .java .opcua .readwrite .ChunkType .*;
23
24
27
28
import java .security .cert .CertificateEncodingException ;
28
29
import java .security .cert .CertificateFactory ;
29
30
import java .security .cert .X509Certificate ;
31
+ import java .util .Map .Entry ;
30
32
import java .util .concurrent .ScheduledExecutorService ;
31
33
import java .util .concurrent .ScheduledFuture ;
32
34
import java .util .concurrent .TimeUnit ;
56
58
import java .util .concurrent .CompletableFuture ;
57
59
import java .util .regex .Matcher ;
58
60
import java .util .regex .Pattern ;
59
- import java .util .stream .Stream ;
60
61
61
62
import static java .util .concurrent .Executors .newSingleThreadExecutor ;
62
63
@@ -82,8 +83,6 @@ public class SecureChannel {
82
83
private final String sessionName = "UaSession:" + APPLICATION_TEXT .getStringValue () + ":" + RandomStringUtils .random (20 , true , true );
83
84
private final PascalByteString localCertificateString ;
84
85
private final PascalByteString remoteCertificateThumbprint ;
85
- private PascalString policyId ;
86
- private UserTokenType tokenType ;
87
86
private final PascalString endpoint ;
88
87
private final String username ;
89
88
private final String password ;
@@ -324,13 +323,14 @@ private CompletableFuture<ActivateSessionResponse> onConnectActivateSessionReque
324
323
LOGGER .debug ("error getting host" , e );
325
324
}
326
325
327
- selectEndpoint (sessionResponse );
328
-
329
- if (this .policyId == null ) {
326
+ Entry <EndpointDescription , UserTokenPolicy > endpointAndAuthPolicy = selectEndpoint (sessionResponse );
327
+ if (endpointAndAuthPolicy == null ) {
330
328
throw new PlcRuntimeException ("Unable to find endpoint - " + endpoints [1 ]);
331
329
}
332
330
333
- ExtensionObject userIdentityToken = getIdentityToken (this .tokenType , policyId .getStringValue ());
331
+ PascalString policyId = endpointAndAuthPolicy .getValue ().getPolicyId ();
332
+ UserTokenType tokenType = endpointAndAuthPolicy .getValue ().getTokenType ();
333
+ ExtensionObject userIdentityToken = getIdentityToken (tokenType , policyId .getStringValue ());
334
334
RequestHeader requestHeader = conversation .createRequestHeader ();
335
335
SignatureData clientSignature = new SignatureData (NULL_STRING , NULL_BYTE_STRING );
336
336
if (conversation .getSecurityPolicy () != SecurityPolicy .NONE ) {
@@ -501,31 +501,34 @@ private static ReadBufferByteBased toBuffer(Supplier<Payload> supplier) {
501
501
}
502
502
503
503
/**
504
- * Selects the endpoint to use based on the connection string provided.
505
- * If Discovery is disabled it will use the host address return from the server
504
+ * Selects the endpoint and authentication policy based on client settings.
506
505
*
507
506
* @param sessionResponse - The CreateSessionResponse message returned by the server
508
- * @throws PlcRuntimeException - If no endpoint with a compatible policy is found raise and error .
507
+ * @return Entry representing desired server endpoint and user token policy to access it .
509
508
*/
510
- private void selectEndpoint (CreateSessionResponse sessionResponse ) throws PlcRuntimeException {
509
+ private Entry < EndpointDescription , UserTokenPolicy > selectEndpoint (CreateSessionResponse sessionResponse ) {
511
510
// Get a list of the endpoints which match ours.
512
- Stream <EndpointDescription > filteredEndpoints = sessionResponse .getServerEndpoints ().stream ()
513
- .map (e -> (EndpointDescription ) e )
514
- .filter (this ::isEndpoint );
515
-
516
- //Determine if the requested security policy is included in the endpoint
517
- filteredEndpoints .forEach (endpoint -> hasIdentity (
518
- endpoint .getUserIdentityTokens ().stream ()
519
- .map (p -> (UserTokenPolicy ) p )
520
- .toArray (UserTokenPolicy []::new )
521
- ));
522
-
523
- if (this .policyId == null ) {
524
- throw new PlcRuntimeException ("Unable to find endpoint - " + this .endpoints .get (0 ));
511
+ EndpointDescription selectedEndpoint = null ;
512
+ for (ExtensionObjectDefinition endpoint : sessionResponse .getServerEndpoints ()) {
513
+ if (!(endpoint instanceof EndpointDescription )) {
514
+ continue ;
515
+ }
516
+ if (isEndpoint ((EndpointDescription ) endpoint )) {
517
+ selectedEndpoint = (EndpointDescription ) endpoint ;
518
+ break ;
519
+ }
525
520
}
526
- if (this .tokenType == null ) {
527
- throw new PlcRuntimeException ("Unable to find Security Policy for endpoint - " + this .endpoints .get (0 ));
521
+
522
+ for (ExtensionObjectDefinition tokenPolicy : selectedEndpoint .getUserIdentityTokens ()) {
523
+ if (!(tokenPolicy instanceof UserTokenPolicy )) {
524
+ continue ;
525
+ }
526
+ if (hasIdentity ((UserTokenPolicy ) tokenPolicy )) {
527
+ return entry (selectedEndpoint , (UserTokenPolicy ) tokenPolicy );
528
+ }
528
529
}
530
+
531
+ return null ;
529
532
}
530
533
531
534
/**
@@ -569,21 +572,16 @@ private boolean isEndpoint(EndpointDescription endpoint) throws PlcRuntimeExcept
569
572
}
570
573
571
574
/**
572
- * Confirms that a policy that matches the connection string is available from
573
- * the returned endpoints. It sets the policyId and tokenType for the policy to use.
575
+ * Confirms that given policy matches the connection string used by client.
574
576
*
575
- * @param policies - A list of policies returned with the endpoint description.
577
+ * @param policy - UserTokenPolicy configured for server endpoint.
578
+ * @return True if given token policy matches client configuration.
576
579
*/
577
- private void hasIdentity (UserTokenPolicy [] policies ) {
578
- for (UserTokenPolicy identityToken : policies ) {
579
- if ((identityToken .getTokenType () == UserTokenType .userTokenTypeAnonymous ) && (this .username == null )) {
580
- policyId = identityToken .getPolicyId ();
581
- tokenType = identityToken .getTokenType ();
582
- } else if ((identityToken .getTokenType () == UserTokenType .userTokenTypeUserName ) && (this .username != null )) {
583
- policyId = identityToken .getPolicyId ();
584
- tokenType = identityToken .getTokenType ();
585
- }
580
+ private boolean hasIdentity (UserTokenPolicy policy ) {
581
+ if ((policy .getTokenType () == UserTokenType .userTokenTypeAnonymous ) && this .username == null ) {
582
+ return true ;
586
583
}
584
+ return policy .getTokenType () == UserTokenType .userTokenTypeUserName && this .username != null ;
587
585
}
588
586
589
587
/**
0 commit comments