Client Authentication
Working with client sessions
After opening a secure channel, the client needs to create a session. The client will receive a set of endpoints and a list of supported user identity token policies in response.
local session, err = client:createSession("test_session", 3600000)
if err ~= nil then
error("Creating session failed: "..err)
end
local tokenPolicy
for _, endpoint in ipairs(session.ServerEndpoints) do
for _, policy in ipairs(endpoint.UserIdentityTokens) do
if policy.TokenType == ua.UserTokenType.UserName and
(policy.SecurityPolicyUri == nil or policy.SecurityPolicyUri == ua.SecurityPolicy.None)
then
tokenPolicy = policy
goto found
end
end
end
::found::
if not tokenPolicy then
error("cannot find endpoint with username token.")
end
local userName = "admin"
local password = "12345"
local resp, err = client:activateSession(tokenPolicy.PolicyId, userName, password)
if err ~= nil then
error("Activating session failed: "..err)
end
Each token policy contains several fields. These fields are common to all policy types:
Field |
Description |
|---|---|
|
Server-assigned policy identifier. The client sends it back so the server can interpret the user token. |
|
Token type: Anonymous, UserName, Certificate, or IssuedToken. |
|
Security policy URI used to secure the token. |
Additional fields are specific to each token type and will be covered in the following sections.
Anonymous
An anonymous token basically means the absence of authentication, which means anyone can connect to and work with the server. This type of authentication is usually enabled for testing purposes only.
You can pass the identifier of the anonymous policy, which is taken from the response of CreateSession. No additional parameters are required for the anonymous token.
-- Create session with name "test_session" and with life time
-- 1 hour (3600000 ms)
local session, err = client:createSession("test_session", 3600000)
local tokenPolicy
for _, endpoint in ipairs(session.ServerEndpoints) do
for _, policy in ipairs(endpoint.UserIdentityTokens) do
if policy.TokenType == ua.UserTokenType.Anonymous
then
tokenPolicy = policy
goto found
end
end
end
::found::
if not tokenPolicy then
error("cannot find endpoint with anonymous token.")
end
-- Passing id of anonymous token policy.
local resp, err = client:activateSession(tokenPolicy.PolicyId)
User Name
Depending on the server configuration, a password can be sent encrypted or unencrypted, which depends on the token policy configuration on the server.
The Username token policy has these parameters:
Field |
Description |
|---|---|
|
Server-assigned policy identifier. |
|
|
|
Security policy used to encrypt the password. If absent or set to
|
The following example demonstrates how to authenticate with a server using a username and password:
local session, err = client:createSession("test_session", 3600000)
if err ~= nil then
error("Creating session failed: "..err)
end
local tokenPolicy
for _, endpoint in ipairs(session.ServerEndpoints) do
for _, policy in ipairs(endpoint.UserIdentityTokens) do
if policy.TokenType == ua.UserTokenType.UserName and
(policy.SecurityPolicyUri == nil or policy.SecurityPolicyUri == ua.SecurityPolicy.None)
then
tokenPolicy = policy
goto found
end
end
end
::found::
if not tokenPolicy then
error("cannot find endpoint with username token.")
end
local userName = "admin"
local password = "12345"
local resp, err = client:activateSession(tokenPolicy.PolicyId, userName, password)
if err ~= nil then
error("Activating session failed: "..err)
end
x509 certificate
To authenticate with a certificate, you need to find the ID of the policy with the type ua.UserTokenPolicy.Certificate.
This policy has these parameters:
Field |
Description |
|---|---|
|
Server-assigned policy identifier. |
|
|
|
Security policy that controls whether the client sends a signature. The
signature is calculated with the user’s private key and proves ownership
of the certificate. If absent or set to |
When activating a session with certificate-based authentication, the ActivateSession call should include these parameters:
Field |
Description |
|---|---|
|
Certificate token policy identifier. |
|
|
|
User certificate sent to the server. |
|
Private key for the user certificate. Used to calculate the signature. |
ActivateSession accepts certificate and private key in PEM or DER format, or a path to files can be passed.
The following example shows how to authenticate using a certificate:
error("Opening secure channel failed: "..err)
end
local session, err = client:createSession("test_session", 3600000)
local tokenPolicy
for _, endpoint in ipairs(session.ServerEndpoints) do
-- Select certificate token policy with security policy Basic128Rsa15
for _, policy in ipairs(endpoint.UserIdentityTokens) do
if policy.TokenType == ua.UserTokenType.Certificate then
tokenPolicy = policy
goto found
end
end
end
::found::
if not tokenPolicy then
error("cannot find endpoint with certificate token policy.")
end
local certificate = mako.cfgdir.."/../certs/client.pem"
local privateKey = mako.cfgdir.."/../certs/client.key"
local resp, err = client:activateSession(
tokenPolicy.PolicyId, certificate, privateKey)
JWT, OAuth2, Azure
OPC UA allows authentication using third-party tokens, which are also known as Issued Tokens.
To authenticate with such tokens, you need to search for the policy that uses the token type ua.UserTokenPolicy.IssuedToken. This type of token is commonly used for all third-party tokens. To distinguish between token formats, the policy includes an additional parameter called IssuedTokenType.
The IssuedToken policy has these parameters:
Field |
Description |
|---|---|
|
Issued-token policy identifier. |
|
|
|
Token format: |
|
URL of the identity server that issued the token. |
|
Security policy used to encrypt the token. If absent or set to |
The following example shows how to authenticate with issued token:
error("Opening secure channel failed: "..err)
end
local session, err = client:createSession("test_session", 3600000)
local tokenPolicy
for _, endpoint in ipairs(session.ServerEndpoints) do
for _, policy in ipairs(endpoint.UserIdentityTokens) do
-- Select JWT token policy. There also Azure, OAuth2 and OPCUA.
if policy.TokenType == ua.UserTokenType.IssuedToken and
policy.IssuedTokenType == ua.IssuedTokenType.JWT
then
tokenPolicy = policy
goto found
end
end
end
::found::
if not tokenPolicy then
error("cannot find endpoint with certificate token policy.")
end
local jwtHeader = { alg="HS256"}
local jwtPayload = {
sub = "1234567890",
name = "John Doe",
iat = 1516239022
}
local token = require"jwt".sign("my-secret", jwtPayload, jwtHeader)
local resp, err = client:activateSession(tokenPolicy.PolicyId, token)