use of org.eclipse.milo.opcua.stack.core.types.structured.UserIdentityToken in project milo by eclipse.
the class SessionFsmFactory method activateSession.
@SuppressWarnings("Duplicates")
private static CompletableFuture<OpcUaSession> activateSession(FsmContext<State, Event> ctx, OpcUaClient client, CreateSessionResponse csr) {
UaStackClient stackClient = client.getStackClient();
try {
EndpointDescription endpoint = client.getConfig().getEndpoint();
ByteString csrNonce = csr.getServerNonce();
SignedIdentityToken signedIdentityToken = client.getConfig().getIdentityProvider().getIdentityToken(endpoint, csrNonce);
UserIdentityToken userIdentityToken = signedIdentityToken.getToken();
SignatureData userTokenSignature = signedIdentityToken.getSignature();
ActivateSessionRequest request = new ActivateSessionRequest(client.newRequestHeader(csr.getAuthenticationToken()), buildClientSignature(client.getConfig(), csrNonce), new SignedSoftwareCertificate[0], new String[0], ExtensionObject.encode(client.getStaticSerializationContext(), userIdentityToken), userTokenSignature);
LOGGER.debug("[{}] Sending ActivateSessionRequest...", ctx.getInstanceId());
return stackClient.sendRequest(request).thenApply(ActivateSessionResponse.class::cast).thenCompose(asr -> {
ByteString asrNonce = asr.getServerNonce();
// TODO check for repeated nonce?
OpcUaSession session = new OpcUaSession(csr.getAuthenticationToken(), csr.getSessionId(), client.getConfig().getSessionName().get(), csr.getRevisedSessionTimeout(), csr.getMaxRequestMessageSize(), csr.getServerCertificate(), csr.getServerSoftwareCertificates());
session.setServerNonce(asrNonce);
return completedFuture(session);
});
} catch (Exception ex) {
return failedFuture(ex);
}
}
use of org.eclipse.milo.opcua.stack.core.types.structured.UserIdentityToken in project milo by eclipse.
the class SessionManager method activateSession.
private ActivateSessionResponse activateSession(ServiceRequest serviceRequest) throws UaException {
ActivateSessionRequest request = (ActivateSessionRequest) serviceRequest.getRequest();
long secureChannelId = serviceRequest.getSecureChannelId();
NodeId authToken = request.getRequestHeader().getAuthenticationToken();
List<SignedSoftwareCertificate> clientSoftwareCertificates = l(request.getClientSoftwareCertificates());
Session session = createdSessions.get(authToken);
if (session == null) {
session = activeSessions.get(authToken);
if (session == null) {
throw new UaException(StatusCodes.Bad_SessionIdInvalid);
} else {
verifyClientSignature(session, request);
SecurityConfiguration securityConfiguration = session.getSecurityConfiguration();
if (session.getSecureChannelId() == secureChannelId) {
/*
* Identity change
*/
UserIdentityToken identityToken = decodeIdentityToken(request.getUserIdentityToken(), session.getEndpoint().getUserIdentityTokens());
Object identityObject = validateIdentityToken(session, identityToken, request.getUserTokenSignature());
StatusCode[] results = new StatusCode[clientSoftwareCertificates.size()];
Arrays.fill(results, StatusCode.GOOD);
ByteString serverNonce = NonceUtil.generateNonce(32);
session.setClientAddress(serviceRequest.getClientAddress());
session.setIdentityObject(identityObject, identityToken);
session.setLastNonce(serverNonce);
session.setLocaleIds(request.getLocaleIds());
return new ActivateSessionResponse(serviceRequest.createResponseHeader(), serverNonce, results, new DiagnosticInfo[0]);
} else {
/*
* Associate session with new secure channel if client certificate and identity token match.
*/
ByteString clientCertificateBytes = serviceRequest.getClientCertificateBytes();
UserIdentityToken identityToken = decodeIdentityToken(request.getUserIdentityToken(), session.getEndpoint().getUserIdentityTokens());
Object identityObject = validateIdentityToken(session, identityToken, request.getUserTokenSignature());
boolean sameIdentity = Objects.equal(identityObject, session.getIdentityObject());
boolean sameCertificate = Objects.equal(clientCertificateBytes, securityConfiguration.getClientCertificateBytes());
if (sameIdentity && sameCertificate) {
SecurityConfiguration newSecurityConfiguration = createSecurityConfiguration(serviceRequest.getEndpoint(), clientCertificateBytes);
session.setEndpoint(serviceRequest.getEndpoint());
session.setSecureChannelId(secureChannelId);
session.setSecurityConfiguration(newSecurityConfiguration);
logger.debug("Session id={} is now associated with secureChannelId={}", session.getSessionId(), secureChannelId);
StatusCode[] results = new StatusCode[clientSoftwareCertificates.size()];
Arrays.fill(results, StatusCode.GOOD);
ByteString serverNonce = NonceUtil.generateNonce(32);
session.setClientAddress(serviceRequest.getClientAddress());
session.setLastNonce(serverNonce);
session.setLocaleIds(request.getLocaleIds());
return new ActivateSessionResponse(serviceRequest.createResponseHeader(), serverNonce, results, new DiagnosticInfo[0]);
} else {
throw new UaException(StatusCodes.Bad_SecurityChecksFailed);
}
}
}
} else {
if (secureChannelId != session.getSecureChannelId()) {
throw new UaException(StatusCodes.Bad_SecurityChecksFailed);
}
verifyClientSignature(session, request);
UserIdentityToken identityToken = decodeIdentityToken(request.getUserIdentityToken(), session.getEndpoint().getUserIdentityTokens());
Object identityObject = validateIdentityToken(session, identityToken, request.getUserTokenSignature());
createdSessions.remove(authToken);
activeSessions.put(authToken, session);
StatusCode[] results = new StatusCode[clientSoftwareCertificates.size()];
Arrays.fill(results, StatusCode.GOOD);
ByteString serverNonce = NonceUtil.generateNonce(32);
session.setClientAddress(serviceRequest.getClientAddress());
session.setIdentityObject(identityObject, identityToken);
session.setLocaleIds(request.getLocaleIds());
session.setLastNonce(serverNonce);
return new ActivateSessionResponse(serviceRequest.createResponseHeader(), serverNonce, results, new DiagnosticInfo[0]);
}
}
use of org.eclipse.milo.opcua.stack.core.types.structured.UserIdentityToken in project milo by eclipse.
the class SessionManager method validateIdentityToken.
private Object validateIdentityToken(Session session, Object tokenObject, SignatureData tokenSignature) throws UaException {
IdentityValidator identityValidator = server.getConfig().getIdentityValidator();
UserTokenPolicy tokenPolicy = validatePolicyId(session, tokenObject);
if (tokenObject instanceof UserIdentityToken) {
return identityValidator.validateIdentityToken(session, (UserIdentityToken) tokenObject, tokenPolicy, tokenSignature);
} else {
throw new UaException(StatusCodes.Bad_IdentityTokenInvalid);
}
}
use of org.eclipse.milo.opcua.stack.core.types.structured.UserIdentityToken in project milo by eclipse.
the class SessionManager method validatePolicyId.
/**
* Validates the policyId on a {@link UserIdentityToken} Object is a policyId that exists on the Endpoint that
* {@code session} is connected to.
*
* @param session the current {@link Session}
* @param tokenObject the {@link UserIdentityToken} Object from the client.
* @return the first {@link UserTokenPolicy} on the Endpoint matching the policyId.
* @throws UaException if the token object is invalid or no matching policy is found.
*/
private UserTokenPolicy validatePolicyId(Session session, Object tokenObject) throws UaException {
if (tokenObject instanceof UserIdentityToken) {
UserIdentityToken token = (UserIdentityToken) tokenObject;
String policyId = token.getPolicyId();
List<UserTokenPolicy> userIdentityTokens = l(session.getEndpoint().getUserIdentityTokens());
Optional<UserTokenPolicy> policy = userIdentityTokens.stream().filter(t -> Objects.equal(policyId, t.getPolicyId())).findFirst();
return policy.orElseThrow(() -> new UaException(StatusCodes.Bad_IdentityTokenInvalid, "policy not found: " + policyId));
} else {
throw new UaException(StatusCodes.Bad_IdentityTokenInvalid);
}
}
Aggregations