Swift sample to login using non-interactive method with ssl key

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • maxspeed
    Junior Member
    • Aug 2014
    • 6

    #1

    Swift sample to login using non-interactive method with ssl key

    Hello Betfair programmers, could you please share your code with newbie?
    or correct this code
    import Foundation
    import UIKit
    import Security


    class ViewController: UIViewController {

    override func viewDidLoad() {
    super.viewDidLoad()
    // let sess = SessionToken()
    login()

    // Do any additional setup after loading the view.
    }
    }
    func login(){



    let appId = ""
    let username = ""
    let password = ""
    let encodedUsername = username.addingPercentEncoding(withAllowedCharacte rs: .urlQueryAllowed)!
    let encodedPassword = password.addingPercentEncoding(withAllowedCharacte rs: .urlQueryAllowed)!




    let urlString = "https://identitysso-cert.betfair.com/api/certlogin"
    let url = URL(string: urlString)!

    let sessionConfig = URLSessionConfiguration.default
    let session = URLSession(configuration: sessionConfig)




    //print Bundle.main.path

    let clientCertPath = Bundle.main.path(forResource: "TestApp1", ofType: "crt")!
    let clientCertData = try! Data(contentsOf: URL(fileURLWithPath: clientCertPath))
    let clientKeyPath = Bundle.main.path(forResource: "TestApp1", ofType: "key")!
    let clientKeyData = try! Data(contentsOf: URL(fileURLWithPath: clientKeyPath))



    let certAndKey = clientCertData + clientKeyData
    let certAndKeyBase64 = certAndKey.base64EncodedString()

    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.addValue(appId, forHTTPHeaderField: "X-Application")
    request.httpBody = "username=\(encodedUsername)&password=\(encode dPas sword)".data(using: .utf8)

    let authValue = "Basic \(certAndKeyBase64)"
    request.setValue(authValue, forHTTPHeaderField: "Authorization")

    let task = session.dataTask(with: request) { data, response, error in
    guard error == nil else {
    print("Error: \(error!)")
    return
    }

    guard let data = data, let response = response as? HTTPURLResponse else {
    print("No data or response received.")
    return
    }

    print("Response status code: \(response.statusCode)")
    print("Response body: \(String(data: data, encoding: .utf8) ?? "")")
    }

    task.resume()

    }



    it has returned CERT_AUTH_REQUIRED
  • Spen1964
    Junior Member
    • Mar 2023
    • 1

    #2

    To login using a non-interactive method with SSL key in Swift, you can use the following code:

    HTML Code:
    import Foundation
    
    func login() {
    
        let appId = "YOUR_APP_ID"
        let username = "YOUR_USERNAME"
        let password = "YOUR_PASSWORD"
    
        let urlString = "https://identitysso-cert.betfair.com/api/certlogin"
        let url = URL(string: urlString)!
    
        let sessionConfig = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfig)
    
        let clientCertPath = Bundle.main.path(forResource: "clientCert", ofType: "p12")!
        let clientCertData = try! Data(contentsOf: URL(fileURLWithPath: clientCertPath))
    
        let identityAndTrust = getClientIdentityAndTrust()
        let credential = URLCredential(identity: identityAndTrust.identity, certificates: identityAndTrust.certificates, persistence: .forSession)
    
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.addValue(appId, forHTTPHeaderField: "X-Application")
        request.httpBody = "username=\(username)&password=\(password)".data(using: .utf8)
        request.urlCredential = credential
    
        let task = session.dataTask(with: request) { data, response, error in
            guard error == nil else {
                print("Error: \(error!)")
                return
            }
    
            guard let data = data, let response = response as? HTTPURLResponse else {
                print("No data or response received.")
                return
            }
    
            print("Response status code: \(response.statusCode)")
            print("Response body: \(String(data: data, encoding: .utf8) ?? "")")
        }
    
        task.resume()
    }
    
    func getClientIdentityAndTrust() -> (identity: SecIdentity, certificates: [SecCertificate]) {
        let path: String = Bundle.main.path(forResource: "clientCert", ofType: "p12")!
        let password: String = "YOUR_PASSWORD"
        let PKCS12Data = NSData(contentsOfFile:path)!
        let key : NSString = kSecImportExportPassphrase as NSString
        let options : NSDictionary = [key : password]
        var items: CFArray?
        let securityError = SecPKCS12Import(PKCS12Data, options, &items)
        guard securityError == errSecSuccess else {
            print("Failed to import PKCS12 certificate with error: \(securityError)")
            return (SecIdentity(), [])
        }
        let itemArray = items! as CFArray
        let dictArray = itemArray as! Array<Dictionary<String,Any>>
        let dict = dictArray.first!
        let identity = dict[kSecImportItemIdentity as String] as! SecIdentity
        let secCertRef = dict[kSecImportItemCertChain as String] as! SecCertificate
        let certArray = [secCertRef] as CFArray
        let certificates = certArray as! [SecCertificate]
        return (identity, certificates)
    }
    ​
    Note: This code assumes that the client certificate is in the PKCS12 format and is located in the app bundle. You may need to modify the code if your certificate is in a different format or is located elsewhere.

    Comment

    Working...
    X