private void DeleteTokenPolicy(int number) { UserTokenPolicy userTokenPolicy = new UserTokenPolicy(); switch (number) { case 0: userTokenPolicy.TokenType = UserTokenType.Anonymous; break; case 1: userTokenPolicy.TokenType = UserTokenType.UserName; break; case 2: userTokenPolicy.TokenType = UserTokenType.Certificate; break; default: userTokenPolicy.TokenType = UserTokenType.Anonymous; break; } foreach (UserTokenPolicy userToken in m_configuration.ServerConfiguration.UserTokenPolicies) { if (userTokenPolicy.TokenType == userToken.TokenType) { m_configuration.ServerConfiguration.UserTokenPolicies.Remove(userToken); } break; } }
/// <summary> /// Creates the objects used to validate the user identity tokens supported by the server. /// </summary> private void CreateUserIdentityValidators(ApplicationConfiguration configuration) { for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++) { UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii]; // create a validator for a certificate token policy. if (policy.TokenType == UserTokenType.Certificate) { // check if user certificate trust lists are specified in configuration. if (configuration.SecurityConfiguration.TrustedUserCertificates != null && configuration.SecurityConfiguration.UserIssuerCertificates != null) { CertificateValidator certificateValidator = new CertificateValidator(); certificateValidator.Update(configuration.SecurityConfiguration).Wait(); certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates, configuration.SecurityConfiguration.TrustedUserCertificates, configuration.SecurityConfiguration.RejectedCertificateStore); // set custom validator for user certificates. m_certificateValidator = certificateValidator.GetChannelValidator(); } } } }
/// <summary> /// Creates the endpoints and creates the hosts. /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="bindingFactory">The binding factory.</param> /// <param name="serverDescription">The server description.</param> /// <param name="endpoints">The endpoints.</param> /// <returns> /// Returns IList of a host for a UA service which type is <seealso cref="ServiceHost"/>. /// </returns> protected override IList <Task> InitializeServiceHosts( ApplicationConfiguration configuration, out ApplicationDescription serverDescription, out EndpointDescriptionCollection endpoints) { serverDescription = null; endpoints = null; Dictionary <string, Task> hosts = new Dictionary <string, Task>(); // ensure at least one security policy exists. if (configuration.ServerConfiguration.SecurityPolicies.Count == 0) { configuration.ServerConfiguration.SecurityPolicies.Add(new ServerSecurityPolicy()); } // ensure at least one user token policy exists. if (configuration.ServerConfiguration.UserTokenPolicies.Count == 0) { UserTokenPolicy userTokenPolicy = new UserTokenPolicy(); userTokenPolicy.TokenType = UserTokenType.Anonymous; userTokenPolicy.PolicyId = userTokenPolicy.TokenType.ToString(); configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy); } // set server description. serverDescription = new ApplicationDescription(); serverDescription.ApplicationUri = configuration.ApplicationUri; serverDescription.ApplicationName = new LocalizedText("en-US", configuration.ApplicationName); serverDescription.ApplicationType = configuration.ApplicationType; serverDescription.ProductUri = configuration.ProductUri; serverDescription.DiscoveryUrls = GetDiscoveryUrls(); endpoints = new EndpointDescriptionCollection(); IList <EndpointDescription> endpointsForHost = null; // create UA TCP host. endpointsForHost = CreateUaTcpServiceHost( hosts, configuration, configuration.ServerConfiguration.BaseAddresses, serverDescription, configuration.ServerConfiguration.SecurityPolicies); endpoints.InsertRange(0, endpointsForHost); // create HTTPS host. endpointsForHost = CreateHttpsServiceHost( hosts, configuration, configuration.ServerConfiguration.BaseAddresses, serverDescription, configuration.ServerConfiguration.SecurityPolicies); endpoints.AddRange(endpointsForHost); return(new List <Task>(hosts.Values)); }
/// <summary> /// Creates the objects used to validate the user identity tokens supported by the server. /// </summary> private void CreateUserIdentityValidators(ApplicationConfiguration configuration) { for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++) { UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii]; // create a validator for a certificate token policy. if (policy.TokenType == UserTokenType.Certificate) { // the name of the element in the configuration file. XmlQualifiedName qname = new XmlQualifiedName(policy.PolicyId, Opc.Ua.Namespaces.OpcUa); // find the location of the trusted issuers. CertificateTrustList trustedIssuers = configuration.ParseExtension <CertificateTrustList>(qname); if (trustedIssuers == null) { Utils.Trace( (int)Utils.TraceMasks.Error, "Could not load CertificateTrustList for UserTokenPolicy {0}", policy.PolicyId); continue; } // trusts any certificate in the trusted people store. m_certificateValidator = X509CertificateValidator.PeerTrust; } } }
/// <summary> /// Creates the objects used to validate the user identity tokens supported by the server. /// </summary> private void CreateUserIdentityValidators(ApplicationConfiguration configuration) { for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++) { UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii]; // ignore policies without an explicit id. if (String.IsNullOrEmpty(policy.PolicyId)) { continue; } // create a validator for an issued token policy. if (policy.TokenType == UserTokenType.IssuedToken) { // the name of the element in the configuration file. XmlQualifiedName qname = new XmlQualifiedName(policy.PolicyId, Namespaces.OpcUa); // find the id for the issuer certificate. CertificateIdentifier id = configuration.ParseExtension <CertificateIdentifier>(qname); if (id == null) { Utils.Trace( (int)Utils.TraceMasks.Error, "Could not load CertificateIdentifier for UserTokenPolicy {0}", policy.PolicyId); continue; } m_tokenResolver = CreateSecurityTokenResolver(id); m_tokenSerializer = WSSecurityTokenSerializer.DefaultInstance; } // create a validator for a certificate token policy. if (policy.TokenType == UserTokenType.Certificate) { // the name of the element in the configuration file. XmlQualifiedName qname = new XmlQualifiedName(policy.PolicyId, Namespaces.OpcUa); // find the location of the trusted issuers. CertificateTrustList trustedIssuers = configuration.ParseExtension <CertificateTrustList>(qname); if (trustedIssuers == null) { Utils.Trace( (int)Utils.TraceMasks.Error, "Could not load CertificateTrustList for UserTokenPolicy {0}", policy.PolicyId); continue; } // trusts any certificate in the trusted people store. m_certificateValidator = X509CertificateValidator.PeerTrust; } } }
/// <inheritdoc/> public IApplicationConfigurationBuilderServerSelected AddUserTokenPolicy(UserTokenPolicy userTokenPolicy) { if (userTokenPolicy == null) { throw new ArgumentNullException(nameof(userTokenPolicy)); } ApplicationConfiguration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy); return(this); }
/// <summary> /// Convert user token policy to service model /// </summary> /// <param name="policy"></param> /// <param name="serializer"></param> /// <returns></returns> public static AuthenticationMethodModel ToServiceModel(this UserTokenPolicy policy, IJsonSerializer serializer) { if (policy == null) { return(null); } var result = new AuthenticationMethodModel { Id = policy.PolicyId, SecurityPolicy = policy.SecurityPolicyUri }; switch (policy.TokenType) { case UserTokenType.Anonymous: result.CredentialType = CredentialType.None; break; case UserTokenType.UserName: result.CredentialType = CredentialType.UserName; break; case UserTokenType.Certificate: result.CredentialType = CredentialType.X509Certificate; result.Configuration = policy.IssuerEndpointUrl; break; case UserTokenType.IssuedToken: switch (policy.IssuedTokenType) { case "http://opcfoundation.org/UA/UserToken#JWT": result.CredentialType = CredentialType.JwtToken; try { // See part 6 result.Configuration = serializer.Parse( policy.IssuerEndpointUrl); } catch { // Store as string result.Configuration = policy.IssuerEndpointUrl; } break; default: // TODO return(null); } break; default: return(null); } return(result); }
/// <summary> /// Creates a user identity for the policy. /// </summary> private IUserIdentity CreateUserIdentity(UserTokenPolicy policy) { if (policy == null || policy.TokenType == UserTokenType.Anonymous) { return(null); } if (policy.TokenType == UserTokenType.UserName) { return(new UserIdentity("SomeUser", "password")); } if (policy.TokenType == UserTokenType.Certificate) { X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); try { foreach (X509Certificate2 certificate in store.Certificates) { if (certificate.HasPrivateKey) { return(new UserIdentity(certificate)); } } return(null); } finally { store.Close(); } } if (policy.TokenType == UserTokenType.IssuedToken) { CertificateIdentifier userid = new CertificateIdentifier(); userid.StoreType = CertificateStoreType.Windows; userid.StorePath = "LocalMachine\\Root"; userid.SubjectName = "UASampleRoot"; X509Certificate2 certificate = userid.Find(); X509SecurityToken signingToken = new X509SecurityToken(certificate); SamlSecurityToken token = CreateSAMLToken("*****@*****.**", signingToken); return(new UserIdentity(token)); } throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "User token policy is not supported."); }
/// <summary> /// Caches application description and list of available endpoints. /// </summary> private void InitializeApplicationDescription() { // this method is caches the information the first time a client connects. if (m_application == null) { // the serviceCertificate element in the app.config file controls what certificate is loaded. m_serverCertificate = OperationContext.Current.Host.Credentials.ServiceCertificate.Certificate; // the URL may be the discovery or the session endpoint. need to store the session endpoint. string endpointUrl = OperationContext.Current.Channel.LocalAddress.ToString(); if (endpointUrl.EndsWith("/discovery", StringComparison.InvariantCulture)) { endpointUrl = endpointUrl.Substring(0, endpointUrl.Length - "/discovery".Length); } // The EndpointDescription stores the information specified in the ISessionEndpoint binding. // This structure is used in the UA discovery services and allows client applications to // discover what security settings are used by the server. EndpointDescription endpoint = new EndpointDescription(); endpoint.EndpointUrl = endpointUrl; endpoint.SecurityMode = MessageSecurityMode.SignAndEncrypt_3; endpoint.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15; endpoint.ServerCertificate = m_serverCertificate.GetRawCertData(); endpoint.TransportProfileUri = Profiles.WsHttpXmlTransport; endpoint.Server = new ApplicationDescription(); endpoint.Server.ApplicationUri = ApplicationUri; endpoint.Server.ApplicationType = ApplicationType.Server_0; endpoint.Server.DiscoveryUrls = new ListOfString(); endpoint.Server.DiscoveryUrls.Add(endpointUrl + "/discovery"); // no authorization supported at this time. UserTokenPolicy userTokenPolicy = new UserTokenPolicy(); userTokenPolicy.TokenType = UserTokenType.Anonymous_0; endpoint.UserIdentityTokens = new ListOfUserTokenPolicy(); endpoint.UserIdentityTokens.Add(userTokenPolicy); m_application = endpoint.Server; // If the server supports multiple bindings it will need multiple EndpointDescriptions. These // structures can be constructed automatically from the bindings in the OperationContext object // This example simply hard codes the settings so a mismatch between the app.config could cause // problems. m_endpoints = new ListOfEndpointDescription(); m_endpoints.Add(endpoint); } }
/// <summary> /// Updates an item in the control. /// </summary> protected override void UpdateItem(ListViewItem listItem, object item) { ConfiguredEndpoint endpoint = listItem.Tag as ConfiguredEndpoint; if (endpoint == null) { base.UpdateItem(listItem, endpoint); return; } string hostname = "<Unknown>"; string protocol = "<Unknown>"; Uri uri = endpoint.EndpointUrl; if (uri != null) { hostname = uri.DnsSafeHost; protocol = uri.Scheme; } listItem.SubItems[0].Text = String.Format("{0}", endpoint.Description.Server.ApplicationName); listItem.SubItems[1].Text = String.Format("{0}", hostname); listItem.SubItems[2].Text = String.Format("{0}", protocol); listItem.SubItems[3].Text = String.Format( "{0}/{1}", SecurityPolicies.GetDisplayName(endpoint.Description.SecurityPolicyUri), endpoint.Description.SecurityMode); listItem.SubItems[4].Text = "<Unknown>"; UserTokenPolicy policy = endpoint.SelectedUserTokenPolicy; if (policy != null) { StringBuilder buffer = new StringBuilder(); buffer.Append(policy.TokenType); if (endpoint.UserIdentity != null) { buffer.Append("/"); buffer.Append(endpoint.UserIdentity); } listItem.SubItems[4].Text = buffer.ToString(); } listItem.ImageKey = GuiUtils.Icons.Process; }
/// <summary> /// Decode user identity token from binary extension object. /// </summary> /// <param name="identityToken"></param> /// <param name="policy"></param> /// <returns></returns> private UserIdentityToken DecodeUserIdentityToken(ExtensionObject identityToken, out UserTokenPolicy policy) { if (identityToken.Encoding != ExtensionObjectEncoding.Binary || !typeof(byte[]).IsInstanceOfType(identityToken.Body)) { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided."); } if (!(BaseVariableState.DecodeExtensionObject(null, typeof(UserIdentityToken), identityToken, false) is UserIdentityToken token)) { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided."); } policy = Endpoint.FindUserTokenPolicy(token.PolicyId); if (policy == null) { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "User token policy not supported.", "ValidateUserIdentityToken"); } switch (policy.TokenType) { case UserTokenType.Anonymous: return(BaseVariableState.DecodeExtensionObject(null, typeof(AnonymousIdentityToken), identityToken, true) as AnonymousIdentityToken); case UserTokenType.UserName: return(BaseVariableState.DecodeExtensionObject(null, typeof(UserNameIdentityToken), identityToken, true) as UserNameIdentityToken); case UserTokenType.Certificate: return(BaseVariableState.DecodeExtensionObject(null, typeof(X509IdentityToken), identityToken, true) as X509IdentityToken); case UserTokenType.IssuedToken: return(BaseVariableState.DecodeExtensionObject(null, typeof(IssuedIdentityToken), identityToken, true) as IssuedIdentityToken); default: throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided."); } }
/// <summary> /// Validate user identity /// </summary> /// <param name="newIdentity"></param> /// <param name="userTokenPolicy"></param> /// <returns></returns> private static IUserIdentity ValidateUserIdentity(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy) { System.Diagnostics.Contracts.Contract.Ensures(userTokenPolicy != null); try { IUserIdentity identity = null; IUserIdentity effectiveIdentity = null; // Validate the identity token and impersonate user. // TODO // lock (_eventLock) { // if (_impersonateUser != null) { // // var args = new ImpersonateEventArgs(newIdentity, userTokenPolicy); // _impersonateUser(session, args); // // if (ServiceResult.IsBad(args.IdentityValidationError)) { // error = args.IdentityValidationError; // if (ServiceResult.IsBad(error)) { // throw new ServiceResultException(error); // } // } // else { // identity = args.Identity; // return args.EffectiveIdentity; // } // } // } // check for validation error. if (identity == null) { identity = new UserIdentity(newIdentity); } // use the identity as the effectiveIdentity if not provided. return(effectiveIdentity ?? identity); } catch (ServiceResultException) { throw; } catch (Exception e) { throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, e, "Could not validate user identity token: {0}", newIdentity); } }
/// <summary> /// Updates an item in the control. /// </summary> public void UpdateItem(ListViewItem listItem, object item) { ConfiguredEndpoint endpoint = listItem.Tag as ConfiguredEndpoint; if (endpoint == null) { listItem.Tag = endpoint; return; } string hostname = "<Unknown>"; string protocol = "<Unknown>"; Uri uri = endpoint.EndpointUrl; if (uri != null) { hostname = uri.DnsSafeHost; protocol = uri.Scheme; } String user = "******"; UserTokenPolicy policy = endpoint.SelectedUserTokenPolicy; if (policy != null) { StringBuilder buffer = new StringBuilder(); buffer.Append(policy.TokenType); if (endpoint.UserIdentity != null) { buffer.Append("/"); buffer.Append(endpoint.UserIdentity); } user = buffer.ToString(); } listItem.Content = String.Format("Application: {0}\r\nHost: {1}\r\nProtocol: {2}\r\nSecurity: {3}/{4}\r\nUser: {5}", endpoint.Description.Server.ApplicationName, hostname, protocol, SecurityPolicies.GetDisplayName(endpoint.Description.SecurityPolicyUri), endpoint.Description.SecurityMode, user); }
/// <summary> /// Finds the best match for the current protocol and security selections. /// </summary> private int FindBestUserTokenPolicy(EndpointDescription endpoint) { // filter by the current token type. UserTokenType currentTokenType = UserTokenType.Anonymous; if (UserTokenTypeCB.SelectedIndex != -1) { currentTokenType = (UserTokenType)UserTokenTypeCB.SelectedItem; } // filter by issued token type. string currentIssuedTokenType = (string)IssuedTokenTypeCB.SelectedItem; // find all matching descriptions. UserTokenPolicyCollection matches = new UserTokenPolicyCollection(); if (endpoint != null) { for (int ii = 0; ii < endpoint.UserIdentityTokens.Count; ii++) { UserTokenPolicy policy = endpoint.UserIdentityTokens[ii]; if (currentTokenType != policy.TokenType) { continue; } if (policy.TokenType == UserTokenType.IssuedToken) { if (currentIssuedTokenType != policy.IssuedTokenType) { continue; } } return(ii); } } return(-1); }
private void CreateUserIdentityValidators(ApplicationConfiguration configuration) { for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++) { UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii]; if (policy.TokenType == UserTokenType.Certificate) { if (configuration.SecurityConfiguration.TrustedUserCertificates != null && configuration.SecurityConfiguration.UserIssuerCertificates != null) { CertificateValidator certificateValidator = new CertificateValidator(); certificateValidator.Update(configuration.SecurityConfiguration).Wait(); certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates, configuration.SecurityConfiguration.TrustedUserCertificates, configuration.SecurityConfiguration.RejectedCertificateStore); m_userCertificateValidator = certificateValidator.GetChannelValidator(); } } } }
private IUserIdentity GetKerberosToken() { // need to get the service principal name from the user token policy. UserTokenPolicy policy = (UserTokenPolicy)KerberosTAB.Tag; if (policy == null) { return(null); } // The ServicePrincipalName (SPN) for the UA Server must be specified as the IssuerEndpointUrl // The ServicePrincipalName (SPN) must be registered with the Kerberos Ticket Granting Server (e.g. Windows Domain Controller). // The SPN identifies the host that UA server is running on and the name of the application. // A domain admin must grant delegate permission to the domain account that the UA server runs under. // That can be done with the setspn.exe utility: // setspn -U -S <hostname>/<exename> <domain accountname> // setspn -C -S <hostname>/<exename> <hostname> // The latter form is used if the UA server runs a Windows Service using the builtin Windows Service account. // NOTE: Using the KerberosSecurityTokenProvider without the NetworkCredential parameter will use the // the credentials of the client process, // create the token provider. KerberosSecurityTokenProvider provider = new KerberosSecurityTokenProvider( policy.IssuerEndpointUrl, System.Security.Principal.TokenImpersonationLevel.Impersonation, new System.Net.NetworkCredential(KerberosUserNameTB.Text, KerberosPasswordTB.Text, KerberosDomainTB.Text)); // create the token (1 minute timeout looking for the server). KerberosRequestorSecurityToken token = (KerberosRequestorSecurityToken)provider.GetToken(new TimeSpan(0, 1, 0)); // TODO // return new UserIdentity(token); throw new NotImplementedException(); }
private void AddTokenPolicy(int number) { UserTokenPolicy userTokenPolicy = new UserTokenPolicy(); switch (number) { case 0: userTokenPolicy.TokenType = UserTokenType.Anonymous; break; case 1: userTokenPolicy.TokenType = UserTokenType.UserName; break; case 2: userTokenPolicy.TokenType = UserTokenType.Certificate; break; default: userTokenPolicy.TokenType = UserTokenType.Anonymous; break; } userTokenPolicy.PolicyId = userTokenPolicy.TokenType.ToString(); int i = 0; foreach (UserTokenPolicy userToken in m_configuration.ServerConfiguration.UserTokenPolicies) { if (userTokenPolicy.TokenType == userToken.TokenType) { i++; } } if (i == 0) { m_configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy); } }
/// <summary> /// Convert service model to user token policy /// </summary> /// <param name="policy"></param> /// <returns></returns> public static UserTokenPolicy ToStackModel(this AuthenticationMethodModel policy) { if (policy == null) { return(null); } var result = new UserTokenPolicy { SecurityPolicyUri = policy.SecurityPolicy, PolicyId = policy.Id }; switch (policy.CredentialType) { case CredentialType.None: result.TokenType = UserTokenType.Anonymous; break; case CredentialType.UserName: result.TokenType = UserTokenType.UserName; break; case CredentialType.X509Certificate: result.TokenType = UserTokenType.Certificate; break; case CredentialType.JwtToken: result.TokenType = UserTokenType.IssuedToken; result.IssuedTokenType = "http://opcfoundation.org/UA/UserToken#JWT"; result.IssuerEndpointUrl = policy.Configuration?.ToString(); break; default: return(null); } return(result); }
/// <summary> /// Validates the identity token supplied by the client. /// </summary> private UserIdentityToken ValidateUserIdentityToken( ExtensionObject identityToken, SignatureData userTokenSignature, out UserTokenPolicy policy ) { policy = null; // check for empty token. if (identityToken == null || identityToken.Body == null) { // not changing the token if already activated. if (m_activated) { return null; } // check if an anonymous login is permitted. if (m_endpoint.UserIdentityTokens != null && m_endpoint.UserIdentityTokens.Count > 0) { bool found = false; for (int ii = 0; ii < m_endpoint.UserIdentityTokens.Count; ii++) { if (m_endpoint.UserIdentityTokens[ii].TokenType == UserTokenType.Anonymous) { found = true; policy = m_endpoint.UserIdentityTokens[ii]; break; } } if (!found) { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Anonymous user token policy not supported."); } } // create an anonymous token to use for subsequent validation. AnonymousIdentityToken anonymousToken = new AnonymousIdentityToken(); anonymousToken.PolicyId = policy.PolicyId; return anonymousToken; } UserIdentityToken token = null; // check for unrecognized token. if (!typeof( UserIdentityToken ).IsInstanceOfType( identityToken.Body )) { //handle the use case when the UserIdentityToken is binary encoded over xml message encoding if (identityToken.Encoding == ExtensionObjectEncoding.Binary && typeof( byte[] ).IsInstanceOfType( identityToken.Body )) { UserIdentityToken newToken = BaseVariableState.DecodeExtensionObject( null, typeof( UserIdentityToken ), identityToken, false ) as UserIdentityToken; if (newToken == null) { throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." ); } policy = m_endpoint.FindUserTokenPolicy( newToken.PolicyId ); if (policy == null) { throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "User token policy not supported.", "Opc.Ua.Server.Session.ValidateUserIdentityToken" ); } switch (policy.TokenType) { case UserTokenType.Anonymous: token = BaseVariableState.DecodeExtensionObject( null, typeof( AnonymousIdentityToken ), identityToken, true ) as AnonymousIdentityToken; break; case UserTokenType.UserName: token = BaseVariableState.DecodeExtensionObject( null, typeof( UserNameIdentityToken ), identityToken, true ) as UserNameIdentityToken; break; case UserTokenType.Certificate: token = BaseVariableState.DecodeExtensionObject( null, typeof( X509IdentityToken ), identityToken, true ) as X509IdentityToken; break; case UserTokenType.IssuedToken: token = BaseVariableState.DecodeExtensionObject( null, typeof( IssuedIdentityToken ), identityToken, true ) as IssuedIdentityToken; break; default: throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." ); } } else { throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." ); } } else { // get the token. token = (UserIdentityToken) identityToken.Body; } // find the user token policy. policy = m_endpoint.FindUserTokenPolicy( token.PolicyId ); if (policy == null) { throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, "User token policy not supported."); } // determine the security policy uri. string securityPolicyUri = policy.SecurityPolicyUri; if (String.IsNullOrEmpty( securityPolicyUri )) { securityPolicyUri = m_endpoint.SecurityPolicyUri; } if (ServerBase.RequireEncryption(m_endpoint)) { // decrypt the token. if (m_serverCertificate == null) { m_serverCertificate = CertificateFactory.Create(m_endpoint.ServerCertificate, true); // check for valid certificate. if (m_serverCertificate == null) { throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found."); } } try { token.Decrypt(m_serverCertificate, m_serverNonce, securityPolicyUri); } catch (Exception e) { if (e is ServiceResultException) { throw; } throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, e, "Could not decrypt identity token."); } // verify the signature. if (securityPolicyUri != SecurityPolicies.None) { byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce); if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri)) { throw new ServiceResultException(StatusCodes.BadUserSignatureInvalid, "Invalid user signature!"); } } } // validate user identity token. return token; }
/// <inheritdoc/> public IApplicationConfigurationBuilderServerSelected AddUserTokenPolicy(UserTokenPolicy userTokenPolicy) { ApplicationConfiguration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy); return(this); }
/// <summary> /// Creates the endpoints and creates the hosts. /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="bindingFactory">The binding factory.</param> /// <param name="serverDescription">The server description.</param> /// <param name="endpoints">The endpoints.</param> /// <returns> /// Returns IList of a host for a UA service which type is <seealso cref="ServiceHost"/>. /// </returns> protected override IList<IBackgroundTask> InitializeServiceHosts( ApplicationConfiguration configuration, BindingFactory bindingFactory, out ApplicationDescription serverDescription, out EndpointDescriptionCollection endpoints) { serverDescription = null; endpoints = null; Dictionary<string, IBackgroundTask> hosts = new Dictionary<string, IBackgroundTask>(); // ensure at least one security policy exists. if (configuration.ServerConfiguration.SecurityPolicies.Count == 0) { configuration.ServerConfiguration.SecurityPolicies.Add(new ServerSecurityPolicy()); } // ensure at least one user token policy exists. if (configuration.ServerConfiguration.UserTokenPolicies.Count == 0) { UserTokenPolicy userTokenPolicy = new UserTokenPolicy(); userTokenPolicy.TokenType = UserTokenType.Anonymous; userTokenPolicy.PolicyId = userTokenPolicy.TokenType.ToString(); configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy); } // set server description. serverDescription = new ApplicationDescription(); serverDescription.ApplicationUri = configuration.ApplicationUri; serverDescription.ApplicationName = configuration.ApplicationName; serverDescription.ApplicationType = configuration.ApplicationType; serverDescription.ProductUri = configuration.ProductUri; serverDescription.DiscoveryUrls = GetDiscoveryUrls(); endpoints = new EndpointDescriptionCollection(); IList<EndpointDescription> endpointsForHost = null; // create hosts for protocols that require one endpoints per security policy foreach (ServerSecurityPolicy securityPolicy in configuration.ServerConfiguration.SecurityPolicies) { endpointsForHost = CreateSinglePolicyServiceHost( hosts, configuration, bindingFactory, configuration.ServerConfiguration.BaseAddresses, serverDescription, securityPolicy.SecurityMode, securityPolicy.SecurityPolicyUri, String.Empty); for (int ii = 0; ii < endpointsForHost.Count; ii++) { endpointsForHost[ii].SecurityLevel = securityPolicy.SecurityLevel; } endpoints.AddRange(endpointsForHost); } // create UA TCP host. endpointsForHost = CreateUaTcpServiceHost( hosts, configuration, bindingFactory, configuration.ServerConfiguration.BaseAddresses, serverDescription, configuration.ServerConfiguration.SecurityPolicies); endpoints.InsertRange(0, endpointsForHost); // create HTTPS host. endpointsForHost = CreateHttpsServiceHost( hosts, configuration, bindingFactory, configuration.ServerConfiguration.BaseAddresses, serverDescription, configuration.ServerConfiguration.SecurityPolicies); endpoints.AddRange(endpointsForHost); return new List<IBackgroundTask>(hosts.Values); }
/// <summary> /// Creates a new instance. /// </summary> public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy, EndpointDescription endpointDescription = null) { m_newIdentity = newIdentity; m_userTokenPolicy = userTokenPolicy; m_endpointDescription = endpointDescription; }
/// <summary> /// Validates the identity token supplied by the client. /// </summary> private UserIdentityToken ValidateUserIdentityToken( ExtensionObject identityToken, SignatureData userTokenSignature, out UserTokenPolicy policy) { policy = null; // check for empty token. if (identityToken == null || identityToken.Body == null) { // not changing the token if already activated. if (m_activated) { return(null); } // check if an anonymous login is permitted. if (m_endpoint.UserIdentityTokens != null && m_endpoint.UserIdentityTokens.Count > 0) { bool found = false; for (int ii = 0; ii < m_endpoint.UserIdentityTokens.Count; ii++) { if (m_endpoint.UserIdentityTokens[ii].TokenType == UserTokenType.Anonymous) { found = true; policy = m_endpoint.UserIdentityTokens[ii]; break; } } if (!found) { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Anonymous user token policy not supported."); } } // create an anonymous token to use for subsequent validation. AnonymousIdentityToken anonymousToken = new AnonymousIdentityToken(); anonymousToken.PolicyId = policy.PolicyId; return(anonymousToken); } UserIdentityToken token = null; // check for unrecognized token. if (!typeof(UserIdentityToken).IsInstanceOfType(identityToken.Body)) { //handle the use case when the UserIdentityToken is binary encoded over xml message encoding if (identityToken.Encoding == ExtensionObjectEncoding.Binary && typeof(byte[]).IsInstanceOfType(identityToken.Body)) { UserIdentityToken newToken = BaseVariableState.DecodeExtensionObject(null, typeof(UserIdentityToken), identityToken, false) as UserIdentityToken; if (newToken == null) { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided."); } policy = m_endpoint.FindUserTokenPolicy(newToken.PolicyId); if (policy == null) { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "User token policy not supported.", "Opc.Ua.Server.Session.ValidateUserIdentityToken"); } switch (policy.TokenType) { case UserTokenType.Anonymous: token = BaseVariableState.DecodeExtensionObject(null, typeof(AnonymousIdentityToken), identityToken, true) as AnonymousIdentityToken; break; case UserTokenType.UserName: token = BaseVariableState.DecodeExtensionObject(null, typeof(UserNameIdentityToken), identityToken, true) as UserNameIdentityToken; break; case UserTokenType.Certificate: token = BaseVariableState.DecodeExtensionObject(null, typeof(X509IdentityToken), identityToken, true) as X509IdentityToken; break; case UserTokenType.IssuedToken: token = BaseVariableState.DecodeExtensionObject(null, typeof(IssuedIdentityToken), identityToken, true) as IssuedIdentityToken; break; default: throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided."); } } else { throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided."); } } else { // get the token. token = (UserIdentityToken)identityToken.Body; } // find the user token policy. policy = m_endpoint.FindUserTokenPolicy(token.PolicyId); if (policy == null) { throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, "User token policy not supported."); } // determine the security policy uri. string securityPolicyUri = policy.SecurityPolicyUri; if (String.IsNullOrEmpty(securityPolicyUri)) { securityPolicyUri = m_endpoint.SecurityPolicyUri; } if (ServerBase.RequireEncryption(m_endpoint)) { // decrypt the token. if (m_serverCertificate == null) { m_serverCertificate = CertificateFactory.Create(m_endpoint.ServerCertificate, true); // check for valid certificate. if (m_serverCertificate == null) { throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found."); } } try { token.Decrypt(m_serverCertificate, m_serverNonce, securityPolicyUri); } catch (Exception e) { if (e is ServiceResultException) { throw; } throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, e, "Could not decrypt identity token."); } // verify the signature. if (securityPolicyUri != SecurityPolicies.None) { byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce); if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri)) { throw new ServiceResultException(StatusCodes.BadUserSignatureInvalid, "Invalid user signature!"); } } } // validate user identity token. return(token); }
/// <summary> /// Activates the session and binds it to the current secure channel. /// </summary> public void ValidateBeforeActivate( OperationContext context, SignatureData clientSignature, List <SoftwareCertificate> clientSoftwareCertificates, ExtensionObject userIdentityToken, SignatureData userTokenSignature, StringCollection localeIds, byte[] serverNonce, out UserIdentityToken identityToken, out UserTokenPolicy userTokenPolicy) { lock (m_lock) { // verify that a secure channel was specified. if (context.ChannelContext == null) { throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid); } // verify that the same security policy has been used. EndpointDescription endpoint = context.ChannelContext.EndpointDescription; if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode) { throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected); } // verify the client signature. if (m_clientCertificate != null) { byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce); //byte[] dataToSign = Utils.Append(m_serverCertificateChain, m_serverNonce); if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature)) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid); } } if (!m_activated) { // must active the session on the channel that was used to create it. if (m_secureChannelId != context.ChannelContext.SecureChannelId) { throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid); } } else { // cannot change the certificates after activation. if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0) { throw new ServiceResultException(StatusCodes.BadInvalidArgument); } } // validate the user identity token. identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy); TraceState("VALIDATED"); } }
public UserTokenItem(UserTokenType tokenType) { Policy = new UserTokenPolicy(tokenType); }
/// <summary> /// Creates a new instance. /// </summary> public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy) { m_newIdentity = newIdentity; m_userTokenPolicy = userTokenPolicy; }
public async Task <Session> CreateSession(OPCUAServer server, string sessionName) { try { lock (dicOfSession) { if (dicOfSession.ContainsKey(sessionName)) { return(dicOfSession[sessionName]); } } #region OPCUAServer UAServer objUAServer = new UAServer(); objUAServer.Protocol = server.protocol; objUAServer.SecurityMode = server.securityMode; objUAServer.SecurityPolicy = server.securityMode; objUAServer.SecurityPolicy = server.securityPolicy; objUAServer.UserIdentityString = server.UserIdentityString; objUAServer.ServerName = server.serverName; try { objUAServer.UserIdentity = (UserIdentityType)Enum.Parse(typeof(UserIdentityType), objUAServer.UserIdentityString); } catch { if (objUAServer.UserIdentityString.Equals("Anonymous")) { objUAServer.UserIdentity = UserIdentityType.Anonymous; } else if (objUAServer.UserIdentityString.Equals("UserName")) { objUAServer.UserIdentity = UserIdentityType.UserName; } else { objUAServer.UserIdentity = UserIdentityType.Certificate; } } if (objUAServer.UserIdentity.Equals(UserIdentityType.Certificate)) { objUAServer.IsSecurityStoreEnabled = false; objUAServer.CertificationPath = server.certificationPath; objUAServer.CertificationPassword = server.certificationPassword; } else if (objUAServer.UserIdentity.Equals(UserIdentityType.UserName)) { objUAServer.UserName = server.userName; objUAServer.UserPassword = server.userPassword; } #endregion await CheckAndLoadConfiguration(); // Create the configuration. ApplicationConfiguration configuration = _appConfiguration; // Helpers.CreateClientConfiguration(myServer); // Create the endpoint description. EndpointDescription endpointDescription = Helpers.CreateEndpointDescription(objUAServer); // Create the endpoint configuration (use the application configuration to provide default values). EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration); // The default timeout for a requests sent using the channel. endpointConfiguration.OperationTimeout = 300000; // Use the pure binary encoding on the wire. //OA-2018-04-11 // endpointConfiguration.UseBinaryEncoding = true; if (objUAServer.MessageEncoding.ToLower().Equals("binary")) { endpointConfiguration.UseBinaryEncoding = true; } else { endpointConfiguration.UseBinaryEncoding = false; } IUserIdentity identity; var t = _appConfiguration.SecurityConfiguration.ApplicationCertificate.Find(true); X509Certificate2 clientCertificate = t.Result; UserTokenPolicy poly; if (objUAServer.UserIdentity.Equals(UserIdentityType.UserName)) { identity = new UserIdentity(objUAServer.UserName, objUAServer.UserPassword); poly = new UserTokenPolicy(UserTokenType.UserName); //added by kais wali bool exist = false; foreach (UserTokenPolicy poltemp in endpointDescription.UserIdentityTokens) { if (poltemp.TokenType.ToString() == poly.TokenType.ToString()) { exist = true; break; } } if (!exist) { endpointDescription.UserIdentityTokens.Add(poly); } } else if (objUAServer.UserIdentity.Equals(UserIdentityType.Certificate)) { CertificateIdentifier certificateIdentifier = new CertificateIdentifier(); X509Certificate2 currentCertificate; certificateIdentifier.StoreType = CertificateStoreType.Directory; currentCertificate = new X509Certificate2(objUAServer.CertificationPath, objUAServer.CertificationPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet); if (currentCertificate == null) { throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Could not find certificate: {0}", certificateIdentifier.SubjectName); } identity = new UserIdentity(currentCertificate); // poly = new UserTokenPolicy(UserTokenType.Certificate); //added by kais wali bool exist = false; foreach (UserTokenPolicy poltemp in endpointDescription.UserIdentityTokens) { if (poltemp.TokenType.ToString() == poly.TokenType.ToString()) { exist = true; break; } } if (!exist) { endpointDescription.UserIdentityTokens.Add(poly); } } else { identity = new UserIdentity(); poly = new UserTokenPolicy(UserTokenType.Anonymous); //added by kais wali bool exist = false; foreach (UserTokenPolicy poltemp in endpointDescription.UserIdentityTokens) { if (poltemp.TokenType.ToString() == poly.TokenType.ToString()) { exist = true; break; } } if (!exist) { endpointDescription.UserIdentityTokens.Add(poly); } } // Create the endpoint. ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration); // Update endpoint description using the discovery endpoint. // create message context. ServiceMessageContext messageContext = configuration.CreateMessageContext(); //Set to true in default configuration (If the user have not configured an OPC UA Server in the ONBS) endpoint.UpdateBeforeConnect = false; // update endpoint description using the discovery endpoint. //OA-2018-06-19 Commented /*if (endpoint.UpdateBeforeConnect) * { * BindingFactory bindingFactory = BindingFactory.Create(configuration, messageContext); * endpoint.UpdateFromServer(bindingFactory); * * endpointDescription = endpoint.Description; * endpointConfiguration = endpoint.Configuration; * }*/ // Set up a callback to handle certificate validation errors. // configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); // initialize the channel which will be created with the server. ITransportChannel channel = SessionChannel.Create( configuration, endpointDescription, endpointConfiguration, //clientCertificateChain, clientCertificate, messageContext); // create the session object. //OA-2017-08-15 Session m_session = new Session(channel, configuration, endpoint, clientCertificate); //m_session = new Session(channel, configuration, endpoint, null); //OA-2017-09-20 byte[] certificateData = endpoint.Description.ServerCertificate; //islem Commented serverCertificate if (certificateData != null) //OA-2018-04-27 //serverCertificate = Utils.ParseCertificateBlob(certificateData); // { m_session.ReturnDiagnostics = DiagnosticsMasks.All; } // Register keep alive callback. //islem Commented KeepAlive // m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive); // create the session. try { m_session.Open(sessionName, 60000, identity, null); dicOfSession.Add(sessionName, m_session);//OA-2017-09-20 } catch (Exception e) { } return(m_session); } catch (Exception e) { return(null); } }
/// <summary> /// Activates the session and binds it to the current secure channel. /// </summary> public void ValidateBeforeActivate( OperationContext context, SignatureData clientSignature, List<SoftwareCertificate> clientSoftwareCertificates, ExtensionObject userIdentityToken, SignatureData userTokenSignature, StringCollection localeIds, byte[] serverNonce, out UserIdentityToken identityToken, out UserTokenPolicy userTokenPolicy) { lock (m_lock) { // verify that a secure channel was specified. if (context.ChannelContext == null) { throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid); } // verify that the same security policy has been used. EndpointDescription endpoint = context.ChannelContext.EndpointDescription; if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode) { throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected); } // verify the client signature. if (m_clientCertificate != null) { byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce); if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature)) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid); } } if (!m_activated) { // must active the session on the channel that was used to create it. if (m_secureChannelId != context.ChannelContext.SecureChannelId) { throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid); } } else { // cannot change the certificates after activation. if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0) { throw new ServiceResultException(StatusCodes.BadInvalidArgument); } } // validate the user identity token. identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy); TraceState("VALIDATED"); } }
/// <summary> /// Creates the endpoint description from current selections. /// </summary> private EndpointDescription CreateDescriptionFromSelections() { string currentProtocol = (string)ProtocolCB.SelectedItem; EndpointDescription endpoint = null; for (int ii = 0; ii < m_availableEndpoints.Count; ii++) { Uri url = Utils.ParseUri(m_availableEndpoints[ii].EndpointUrl); if (url == null) { continue; } if (endpoint == null) { endpoint = m_availableEndpoints[ii]; } if (url.Scheme == currentProtocol) { endpoint = m_availableEndpoints[ii]; break; } } UriBuilder builder = null; if (endpoint == null) { builder = new UriBuilder(); builder.Host = "localhost"; if (currentProtocol == Utils.UriSchemeOpcTcp) { builder.Port = Utils.UaTcpDefaultPort; } } else { builder = new UriBuilder(endpoint.EndpointUrl); } builder.Scheme = currentProtocol; endpoint = new EndpointDescription(); endpoint.EndpointUrl = builder.ToString(); endpoint.SecurityMode = (MessageSecurityMode)SecurityModeCB.SelectedItem; endpoint.SecurityPolicyUri = SecurityPolicies.GetUri((string)SecurityPolicyCB.SelectedItem); endpoint.Server.ApplicationName = endpoint.EndpointUrl; endpoint.Server.ApplicationType = ApplicationType.Server; endpoint.Server.ApplicationUri = endpoint.EndpointUrl; UserTokenType userTokenType = (UserTokenType)UserTokenTypeCB.SelectedItem; UserTokenPolicy userTokenPolicy = new UserTokenPolicy(userTokenType); if (userTokenType == UserTokenType.IssuedToken) { userTokenPolicy.IssuedTokenType = (string)IssuedTokenTypeCB.SelectedItem; } endpoint.UserIdentityTokens.Add(userTokenPolicy); return(endpoint); }
public async Task <ConnectionStatus> OpcClient(string endpointURL) { try { Uri endpointURI = new Uri(endpointURL); var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, false, 15000); info.LabelText = "Selected endpoint uses: " + selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1); var endpointConfiguration = EndpointConfiguration.Create(config); var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration); endpoint.Update(selectedEndpoint); var platform = Device.RuntimePlatform; var sessionName = ""; switch (Device.RuntimePlatform) { case "Android": sessionName = "AIS Demonstrator Android Applikation"; break; // other cases are irrelevant for the Industrie 4.0 Demonstrator as of now case "UWP": sessionName = "OPC UA Xamarin Client UWP"; break; case "iOS": sessionName = "OPC UA Xamarin Client IOS"; break; } #region OPC UA User Authentication handling /* * Partially copied from https://github.com/OPCFoundation/UA-.NETStandard/issues/446 */ UserTokenPolicy utp = new UserTokenPolicy(); utp.TokenType = UserTokenType.UserName; UserTokenPolicyCollection utpCollection = new UserTokenPolicyCollection(); utpCollection.Add(utp); selectedEndpoint.UserIdentityTokens = utpCollection; selectedEndpoint.SecurityMode = MessageSecurityMode.SignAndEncrypt; UserIdentity SessionUserIdentity = new UserIdentity(MainActivity.UserName, MainActivity.UserPassword); #endregion session = await Session.Create(config, endpoint, false, sessionName, 30000, SessionUserIdentity, null); if (session != null) { connectionStatus = ConnectionStatus.Connected; #region Subscription + monitoredItems // Code for Monitored Items based on http://opcfoundation.github.io/UA-.NETStandard/help/index.htm#client_development.htm // Create Subscription Subscription subscription = new Subscription() // new Subscription(OpcClient.session.DefaultSubscription) { PublishingInterval = 1000, PublishingEnabled = true }; // CoffeeLevel MonitoredItem CoffeeLevel = new MonitoredItem(subscription.DefaultItem) { StartNodeId = "ns=1;s=CoffeeLevel", DisplayName = "MonitoredCoffeeLevel", AttributeId = Attributes.Value, MonitoringMode = MonitoringMode.Reporting, SamplingInterval = 1000, // check the CoffeeLevel every second QueueSize = 1, // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one DiscardOldest = true // we only need the most recent value for CoffeeLevel }; CoffeeLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueCoffeeLevel); // WaterLevel MonitoredItem WaterLevel = new MonitoredItem(subscription.DefaultItem) { StartNodeId = "ns=1;s=WaterLevel", DisplayName = "MonitoredWaterLevel", AttributeId = Attributes.Value, MonitoringMode = MonitoringMode.Reporting, SamplingInterval = 1000, // check the CoffeeLevel every second QueueSize = 1, // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one DiscardOldest = true // we only need the most recent value for CoffeeLevel }; WaterLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueWaterLevel); // CleanlinessLevel MonitoredItem CleanlinessLevel = new MonitoredItem(subscription.DefaultItem) { StartNodeId = "ns=1;s=Cleanliness", DisplayName = "MonitoredCleanlinessLevel", AttributeId = Attributes.Value, MonitoringMode = MonitoringMode.Reporting, SamplingInterval = 1000, // check the CoffeeLevel every second QueueSize = 1, // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one DiscardOldest = true // we only need the most recent value for CoffeeLevel }; CleanlinessLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueCleanlinessLevel); // add MonitoredItems to Subscription subscription.AddItem(CoffeeLevel); subscription.AddItem(WaterLevel); subscription.AddItem(CleanlinessLevel); // add Subscription to Session session.AddSubscription(subscription); subscription.Create(); #endregion } else { connectionStatus = ConnectionStatus.NotConnected; } // register keep alive handler session.KeepAlive += Client_KeepAlive; } catch { connectionStatus = ConnectionStatus.Error; } return(connectionStatus); }
/// <summary> /// Creates the endpoints and creates the hosts. /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="bindingFactory">The binding factory.</param> /// <param name="serverDescription">The server description.</param> /// <param name="endpoints">The endpoints.</param> /// <returns> /// Returns IList of a host for a UA service which type is <seealso cref="ServiceHost"/>. /// </returns> protected override IList<Task> InitializeServiceHosts( ApplicationConfiguration configuration, out ApplicationDescription serverDescription, out EndpointDescriptionCollection endpoints) { serverDescription = null; endpoints = null; Dictionary<string, Task> hosts = new Dictionary<string, Task>(); // ensure at least one security policy exists. if (configuration.ServerConfiguration.SecurityPolicies.Count == 0) { configuration.ServerConfiguration.SecurityPolicies.Add(new ServerSecurityPolicy()); } // ensure at least one user token policy exists. if (configuration.ServerConfiguration.UserTokenPolicies.Count == 0) { UserTokenPolicy userTokenPolicy = new UserTokenPolicy(); userTokenPolicy.TokenType = UserTokenType.Anonymous; userTokenPolicy.PolicyId = userTokenPolicy.TokenType.ToString(); configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy); } // set server description. serverDescription = new ApplicationDescription(); serverDescription.ApplicationUri = configuration.ApplicationUri; serverDescription.ApplicationName = configuration.ApplicationName; serverDescription.ApplicationType = configuration.ApplicationType; serverDescription.ProductUri = configuration.ProductUri; serverDescription.DiscoveryUrls = GetDiscoveryUrls(); endpoints = new EndpointDescriptionCollection(); IList<EndpointDescription> endpointsForHost = null; // create UA TCP host. endpointsForHost = CreateUaTcpServiceHost( hosts, configuration, configuration.ServerConfiguration.BaseAddresses, serverDescription, configuration.ServerConfiguration.SecurityPolicies); endpoints.InsertRange(0, endpointsForHost); // create HTTPS host. #if !NO_HTTPS endpointsForHost = CreateHttpsServiceHost( hosts, configuration, configuration.ServerConfiguration.BaseAddresses, serverDescription, configuration.ServerConfiguration.SecurityPolicies); endpoints.AddRange(endpointsForHost); #endif return new List<Task>(hosts.Values); }
/// <summary> /// Activates an existing session /// </summary> public virtual bool ActivateSession( OperationContext context, NodeId authenticationToken, SignatureData clientSignature, List <SoftwareCertificate> clientSoftwareCertificates, ExtensionObject userIdentityToken, SignatureData userTokenSignature, StringCollection localeIds, out byte[] serverNonce) { serverNonce = null; Session session = null; UserIdentityToken newIdentity = null; UserTokenPolicy userTokenPolicy = null; lock (m_lock) { // find session. if (!m_sessions.TryGetValue(authenticationToken, out session)) { throw new ServiceResultException(StatusCodes.BadSessionClosed); } // check if session timeout has expired. if (session.HasExpired) { m_server.CloseSession(null, session.Id, false); throw new ServiceResultException(StatusCodes.BadSessionClosed); } // create new server nonce. serverNonce = Utils.Nonce.CreateNonce((uint)m_minNonceLength); // validate before activation. session.ValidateBeforeActivate( context, clientSignature, clientSoftwareCertificates, userIdentityToken, userTokenSignature, localeIds, serverNonce, out newIdentity, out userTokenPolicy); } IUserIdentity identity = null; IUserIdentity effectiveIdentity = null; ServiceResult error = null; try { // check if the application has a callback which validates the identity tokens. lock (m_eventLock) { if (m_ImpersonateUser != null) { ImpersonateEventArgs args = new ImpersonateEventArgs(newIdentity, userTokenPolicy); m_ImpersonateUser(session, args); if (ServiceResult.IsBad(args.IdentityValidationError)) { error = args.IdentityValidationError; } else { identity = args.Identity; effectiveIdentity = args.EffectiveIdentity; } } } // parse the token manually if the identity is not provided. if (identity == null) { identity = new UserIdentity(newIdentity); } // use the identity as the effectiveIdentity if not provided. if (effectiveIdentity == null) { effectiveIdentity = identity; } } catch (Exception e) { if (e is ServiceResultException) { throw e; } throw ServiceResultException.Create( StatusCodes.BadIdentityTokenInvalid, e, "Could not validate user identity token: {0}", newIdentity); } // check for validation error. if (ServiceResult.IsBad(error)) { throw new ServiceResultException(error); } // activate session. bool contextChanged = session.Activate( context, clientSoftwareCertificates, newIdentity, identity, effectiveIdentity, localeIds, serverNonce); // raise session related event. if (contextChanged) { RaiseSessionEvent(session, SessionEventReason.Activated); } // indicates that the identity context for the session has changed. return(contextChanged); }
/// <summary> /// Activates the session and binds it to the current secure channel. /// </summary> public void ValidateBeforeActivate( OperationContext context, SignatureData clientSignature, List <SoftwareCertificate> clientSoftwareCertificates, ExtensionObject userIdentityToken, SignatureData userTokenSignature, StringCollection localeIds, byte[] serverNonce, out UserIdentityToken identityToken, out UserTokenPolicy userTokenPolicy) { lock (m_lock) { // verify that a secure channel was specified. if (context.ChannelContext == null) { throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid); } // verify that the same security policy has been used. EndpointDescription endpoint = context.ChannelContext.EndpointDescription; if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode) { throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected); } // verify the client signature. if (m_clientCertificate != null) { if (m_endpoint.SecurityPolicyUri != SecurityPolicies.None && clientSignature != null && clientSignature.Signature == null) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid); } byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce); if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature)) { // verify for certificate chain in endpoint. // validate the signature with complete chain if the check with leaf certificate failed. X509Certificate2Collection serverCertificateChain = Utils.ParseCertificateChainBlob(m_endpoint.ServerCertificate); if (serverCertificateChain.Count > 1) { List <byte> serverCertificateChainList = new List <byte>(); for (int i = 0; i < serverCertificateChain.Count; i++) { serverCertificateChainList.AddRange(serverCertificateChain[i].RawData); } byte[] serverCertificateChainData = serverCertificateChainList.ToArray(); dataToSign = Utils.Append(serverCertificateChainData, m_serverNonce); if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature)) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid); } } else { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid); } } } if (!m_activated) { // must active the session on the channel that was used to create it. if (m_secureChannelId != context.ChannelContext.SecureChannelId) { throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid); } } else { // cannot change the certificates after activation. if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0) { throw new ServiceResultException(StatusCodes.BadInvalidArgument); } } // validate the user identity token. identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy); TraceState("VALIDATED"); } }
/// <summary> /// Creates a user identity for the policy. /// </summary> private IUserIdentity CreateUserIdentity(UserTokenPolicy policy) { if (policy == null || policy.TokenType == UserTokenType.Anonymous) { return null; } if (policy.TokenType == UserTokenType.UserName) { return new UserIdentity("SomeUser", "password"); } if (policy.TokenType == UserTokenType.Certificate) { X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); try { foreach (X509Certificate2 certificate in store.Certificates) { if (certificate.HasPrivateKey) { return new UserIdentity(certificate); } } return null; } finally { store.Close(); } } if (policy.TokenType == UserTokenType.IssuedToken) { CertificateIdentifier userid = new CertificateIdentifier(); userid.StoreType = CertificateStoreType.Windows; userid.StorePath = "LocalMachine\\Root"; userid.SubjectName = "UASampleRoot"; X509Certificate2 certificate = userid.Find(); X509SecurityToken signingToken = new X509SecurityToken(certificate); SamlSecurityToken token = CreateSAMLToken("*****@*****.**", signingToken); return new UserIdentity(token); } throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "User token policy is not supported."); }
public UserTokenItem(UserTokenPolicy policy) { Policy = policy; }