mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-28 05:57:47 +08:00
reuse usertokenpolicy used in connect for Reconnect / "ReactivateSession" (#3581)
* reuse usertokenpolicy * change assert not null to assert ignore when null * reportauditevent -> Utils.Clone(session?.IdentityToken?.Token) * use standard credentials * only assign to endpoint when not null, in UpdateSession -> also update m_userTokenSecurityPolicyUri, change endpoint configuration only on cloned object * keep using m_userTokenSecurityPolicyUri in Encrypt * use 'cleaner clone'
This commit is contained in:
@@ -1283,6 +1283,8 @@ namespace Opc.Ua.Client
|
||||
previousServerNonce,
|
||||
m_endpoint.Description.SecurityMode);
|
||||
|
||||
m_userTokenSecurityPolicyUri = tokenSecurityPolicyUri;
|
||||
|
||||
// sign data with user token.
|
||||
SignatureData userTokenSignature = identityToken.Sign(
|
||||
dataToSign,
|
||||
@@ -2324,7 +2326,7 @@ namespace Opc.Ua.Client
|
||||
UserTokenPolicy identityPolicy = endpoint.FindUserTokenPolicy(
|
||||
m_identity.TokenType,
|
||||
m_identity.IssuedTokenType,
|
||||
endpoint.SecurityPolicyUri);
|
||||
m_userTokenSecurityPolicyUri ?? endpoint.SecurityPolicyUri);
|
||||
|
||||
if (identityPolicy == null)
|
||||
{
|
||||
@@ -2337,18 +2339,21 @@ namespace Opc.Ua.Client
|
||||
}
|
||||
|
||||
// select the security policy for the user token.
|
||||
string? tokenSecurityPolicyUri = identityPolicy.SecurityPolicyUri;
|
||||
if (string.IsNullOrEmpty(tokenSecurityPolicyUri))
|
||||
if (m_userTokenSecurityPolicyUri == null)
|
||||
{
|
||||
tokenSecurityPolicyUri = endpoint.SecurityPolicyUri;
|
||||
string? tokenSecurityPolicyUri = identityPolicy.SecurityPolicyUri;
|
||||
if (string.IsNullOrEmpty(tokenSecurityPolicyUri))
|
||||
{
|
||||
tokenSecurityPolicyUri = endpoint.SecurityPolicyUri;
|
||||
}
|
||||
m_userTokenSecurityPolicyUri = tokenSecurityPolicyUri;
|
||||
}
|
||||
m_userTokenSecurityPolicyUri = tokenSecurityPolicyUri;
|
||||
|
||||
// validate server nonce and security parameters for user identity.
|
||||
ValidateServerNonce(
|
||||
m_identity,
|
||||
m_serverNonce,
|
||||
tokenSecurityPolicyUri,
|
||||
m_userTokenSecurityPolicyUri,
|
||||
m_previousServerNonce,
|
||||
m_endpoint.Description.SecurityMode);
|
||||
|
||||
@@ -2357,7 +2362,7 @@ namespace Opc.Ua.Client
|
||||
identityToken.UpdatePolicy(identityPolicy);
|
||||
SignatureData userTokenSignature = identityToken.Sign(
|
||||
dataToSign,
|
||||
tokenSecurityPolicyUri);
|
||||
m_userTokenSecurityPolicyUri);
|
||||
|
||||
// encrypt token.
|
||||
identityToken.Encrypt(
|
||||
|
||||
@@ -1072,7 +1072,7 @@ namespace Opc.Ua.Server
|
||||
e.SetChildValue(
|
||||
systemContext,
|
||||
BrowseNames.UserIdentityToken,
|
||||
Utils.Clone(session?.IdentityToken.Token),
|
||||
Utils.Clone(session?.IdentityToken?.Token),
|
||||
false);
|
||||
|
||||
server.ReportAuditEvent(systemContext, e);
|
||||
|
||||
@@ -956,6 +956,65 @@ namespace Opc.Ua.Client.Tests
|
||||
Utils.SilentDispose(session2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a session on a channel using a usertokenpolicy from another endpoint, then reconnect (activate)
|
||||
/// </summary>
|
||||
[Test]
|
||||
[Order(260)]
|
||||
[TestCase(SecurityPolicies.Basic256Sha256, SecurityPolicies.Basic128Rsa15)]
|
||||
public async Task ReconnectSession_ReuseUsertokenPolicyAsync(
|
||||
string securityPolicy, string userTokenPolicy)
|
||||
{
|
||||
|
||||
UserIdentity userIdentity = new UserIdentity("user1", "password"u8);
|
||||
|
||||
// the first channel determines the endpoint
|
||||
ConfiguredEndpoint endpoint = await ClientFixture
|
||||
.GetEndpointAsync(ServerUrl, securityPolicy, Endpoints)
|
||||
.ConfigureAwait(false);
|
||||
if (endpoint == null)
|
||||
{
|
||||
NUnit.Framework.Assert.Ignore(
|
||||
$"No endpoint found for {securityPolicy}");
|
||||
}
|
||||
endpoint = new ConfiguredEndpoint(
|
||||
null,
|
||||
(EndpointDescription)endpoint.Description.MemberwiseClone(),
|
||||
endpoint.Configuration);
|
||||
endpoint.Description.SecurityMode = MessageSecurityMode.Sign;
|
||||
ConfiguredEndpoint tokenPolicyEndpoint = await ClientFixture
|
||||
.GetEndpointAsync(ServerUrl, userTokenPolicy, Endpoints)
|
||||
.ConfigureAwait(false);
|
||||
Assert.NotNull(tokenPolicyEndpoint);
|
||||
|
||||
UserTokenPolicy identityPolicy = endpoint.Description.FindUserTokenPolicy(
|
||||
userIdentity.TokenType,
|
||||
userIdentity.IssuedTokenType,
|
||||
tokenPolicyEndpoint.Description.SecurityPolicyUri);
|
||||
if (identityPolicy == null)
|
||||
{
|
||||
NUnit.Framework.Assert.Ignore(
|
||||
$"No UserTokenPolicy found for {userIdentity.TokenType}" +
|
||||
$" / {userIdentity.IssuedTokenType}");
|
||||
}
|
||||
userIdentity.PolicyId = identityPolicy.PolicyId;
|
||||
|
||||
// the active channel
|
||||
ISession session1 = await ClientFixture.ConnectAsync(endpoint, userIdentity)
|
||||
.ConfigureAwait(false);
|
||||
Assert.NotNull(session1);
|
||||
try
|
||||
{
|
||||
await session1.ReconnectAsync(null, null).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
session1.DeleteSubscriptionsOnClose = true;
|
||||
await session1.CloseAsync(1000).ConfigureAwait(false);
|
||||
Utils.SilentDispose(session1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a session on a channel, then recreate using the session as a template,
|
||||
/// verify the renewUserIdentityHandler is brought to the new session and called
|
||||
|
||||
Reference in New Issue
Block a user