.NET Based OPC UA Client/Server SDK  3.1.0.500
User Authentication

The Demo Server contains an example that shows how to allow users to authenticate with different UserIdentityTokens. The following section gives an overview of the most important parts of the implementation. The complete source code can be found in the Visual Studio solution for the Demo Server (file TestServerManager.cs).

Adding an ImpersonateEventHandler to the SessionManager

This event handler is called in ActivateSession and passes the IdentityToken of the client.

this.SessionManager.ImpersonateUser += new ImpersonateEventHandler(SessionManager_ImpersonateUser);

and

private void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args)

Check for AnonymousIdentityToken

AnonymousIdentityToken anonynmousToken = args.NewIdentity as AnonymousIdentityToken;
if (anonynmousToken != null)
{
return;
}

Check for UserNameIdentityToken

The Demo Server accepts four hard-coded UserNameIdentityTokens as listed in the following table.

UserName Password
john master
joe god
sue curly
root secret
Note
For simplicity, the usernames and passwords in this example are specified in code. In real world applications, you should use some kind of database.

Users with Restricted Access

The users john, joe, and sue have been given restricted access. The code snippet shows the example code for the user john.

UserNameIdentityToken userNameToken = args.NewIdentity as UserNameIdentityToken;
if (userNameToken != null)
{
if (String.IsNullOrEmpty(userNameToken.UserName))
{
args.IdentityValidationError = StatusCodes.BadIdentityTokenInvalid;
return;
}
if (userNameToken.UserName == "john")
{
if (userNameToken.DecryptedPassword != "master")
{
args.IdentityValidationError = StatusCodes.BadUserAccessDenied;
}
return;
}

User root with Administrator Rights

To give the user root administrative rights, the EffectiveIdentity is set.

if (userNameToken.UserName == "root")
{
if (userNameToken.DecryptedPassword != "secret")
{
args.IdentityValidationError = StatusCodes.BadUserAccessDenied;
}
else
{
args.EffectiveIdentity = new UserIdentity(userNameToken, true);
}
return;
}

Logon with Username and Password of the Local Machine

The following code snippets show how to use username and password of the local windows installation for server logon.

LogonUser(userNameToken);
private static class Win32
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
}
private void LogonUser(UserNameIdentityToken identity)
{
IntPtr handle = IntPtr.Zero;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NETWORK = 3;
bool result = Win32.LogonUser(
identity.UserName,
String.Empty,
identity.DecryptedPassword,
LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT,
ref handle);
if (!result)
{
throw new StatusException(StatusCodes.BadUserAccessDenied, "Login failed for user: {0}", identity.UserName);
}
}

Check for X509IdentityToken

Configuration

The support for X509IdentityTokens must be enabled in the UserIdentitySettings that are part of the ServerSettings.

<EnableCertificate>true</EnableCertificate>

If UserTrustedCertificateStore and UserIssuerCertificateStore are configured, UserCertificateValidator for user certificates is created by the ServerManager. This CertificateValidator can be used in the ImpersonateUser EventHandler. If UserTrustedCertificateStore and UserIssuerCertificateStore are not configured, a CertificateValidator must be created by the application.

<UserTrustedCertificateStore>%CommonApplicationData%\unifiedautomation\UaSdkNet\pkiuser\trusted</UserTrustedCertificateStore>
<UserIssuerCertificateStore>%CommonApplicationData%\unifiedautomation\UaSdkNet\pkiuser\issuers</UserIssuerCertificateStore>
<UserRejectedCertificateStore>%CommonApplicationData%\unifiedautomation\UaSdkNet\pkiuser\rejected</UserRejectedCertificateStore>

ImpersonateUser EventHandler

The following code snippet shows how to add use the UserCertificateValidator in the ImpersonateUser EventHandler.

X509IdentityToken certificateToken = args.NewIdentity as X509IdentityToken;
if (certificateToken != null)
{
try
{
// UserCertificateValidator is created by ServerManager since it is configured in ServerSettings.UserIdentity.
UserCertificateValidator.Validate(certificateToken.Certificate);
return;
}
catch (Exception)
{
args.IdentityValidationError = StatusCodes.BadIdentityTokenRejected;
return;
}
}

The EventHandler ServerManager.UntrustedUserCertificate gets called if a user certificate is not trusted or has validation errors. This EventHandler is not implemented in this example.