aws-amplify / aws-sdk-ios

AWS SDK for iOS. For more information, see our web site:
https://aws-amplify.github.io/docs
Other
1.68k stars 885 forks source link

Establish connection to AWSIoTDataManager with a authenticated wss #4000

Closed pakito87 closed 2 years ago

pakito87 commented 2 years ago

State your question i want to establish a connection with the AWSIoTDataManager to subscribe topics, the problem is that i only have access to an authenticated WSS URL and the client ID.

Let me explain, before i establish the connection with the AWS IoT, i need to call a backend endpoint and provide my device UDID, the BE creates the thing on AWS services using my provided UDID and returns an authenticated wss url.

Example: wss://xxx-ats.iot.eu-central-1.amazonaws.com/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxFeu-central-1%2Fiotdevicegateway%2Faws4_request&X-Amz-Date=20220208T141653Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=xx&X-Amz-Security-Token=xxxx

at this point, i have an authenticated wss url and the clientID(its my device UDID). After that, i have to establish the connection with the AWS IoT, but i don't have any poolID or regionID to create the AWSCognitoCredentialsProvider. How can i establish the connection with the iOT without these params? its possible?

Which AWS Services are you utilizing? AWSIoT

Provide code snippets (if applicable)

import AWSIoT
import UIKit

class AWSocketServer : SocketServer {

    var dataManager: AWSIoTDataManager?

    weak var delegate: SockerServerDelegate?

    func connect(url: URL, udid: String) {

        let iotEndPoint = AWSEndpoint(url: url)

        // Create AWS credentials and configuration
        let credentials = AWSCognitoCredentialsProvider(regionType:.Unknown, identityPoolId: "your-identity-pool-id-here")

        let iotDataConfiguration = AWSServiceConfiguration(region: .Unknown,
                                                           endpoint: iotEndPoint,
                                                           credentialsProvider: credentials)  // credentials is the same var as created above

        AWSIoTDataManager.register(with: iotDataConfiguration!, forKey: "kDataManager")

        // Access the AWSDataManager instance as follows:
        dataManager = AWSIoTDataManager(forKey: "kDataManager")
    }

    func registSubscription(topic: String) -> Bool {

        guard let dataManager = dataManager else {
            return false
        }

        return dataManager.subscribe(toTopic: topic, qoS: .messageDeliveryAttemptedAtLeastOnce, messageCallback: self.subscriptionMessageReceived)
    }

    func unregistSubscription(topic: String) {

        guard let dataManager = dataManager else {
            return
        }

        return dataManager.unsubscribeTopic(topic)
    }
}

private extension AWSocketServer {

    func connectToAWSIoT(clientId: String) {

        guard let dataManager = dataManager else {
            return
        }

        DispatchQueue.global(qos: .background).async {
            dataManager.connectUsingWebSocket(withClientId: clientId,
                                              cleanSession: true,
                                              statusCallback: self.mqttEventCallback)
        }
    }

    func mqttEventCallback(_ status: AWSIoTMQTTStatus ) {
        switch status {
        case .connecting: print("Connecting to AWS IoT")
        case .connected:
            print("Connected to AWS IoT")
            // Register subscriptions here
            // Publish a boot message if required
        case .connectionError: print("AWS IoT connection error")
        case .connectionRefused: print("AWS IoT connection refused")
        case .protocolError: print("AWS IoT protocol error")
        case .disconnected: print("AWS IoT disconnected")
        case .unknown: print("AWS IoT unknown state")
        default: print("Error - unknown MQTT state")
        }
    }

    func subscriptionMessageReceived(payload: Data) {
        //call the delegate
    }
}

Environment(please complete the following information):

royjit commented 2 years ago

Here is the documentation of different type of client side authentication for IoT - https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html

We do not currently support passing presigned URL to the AWSIoTDataManager. You could use these apis defined here for connecting via different authentication mechanism.