Created
December 2, 2020 21:28
-
-
Save matthewrobertson/4abaddf5687dbd711d8660f0b1af8e3b to your computer and use it in GitHub Desktop.
Issue an ACS user access token in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Script to issue an ACS user token via HMAC auth as described in this doc: | |
// https://docs.microsoft.com/en-us/azure/communication-services/concepts/authentication?tabs=csharp#sign-an-http-request | |
import UIKit | |
import Foundation | |
import CryptoKit | |
struct FetchTokenResult: Codable { | |
var identity:String | |
var token:String | |
var expiresIn: Int | |
} | |
func fetchToken(endpoint: String, accessKey: String, identity: String? = nil, completionHandler: @escaping (Result<FetchTokenResult, Error>) -> Void) { | |
// create the URL | |
let url = URL(string: "\(endpoint)/identity/token?api-version=2020-07-20-preview1")! | |
// create the JSON body | |
var jsonObject: [String: Any] = ["scopes": ["chat", "voip"]] | |
if let identity = identity { | |
jsonObject["identity"] = identity | |
} | |
let bodyBytes = try! JSONSerialization.data(withJSONObject: jsonObject) | |
// create an SHA256 digest of the body | |
let digest = SHA256.hash(data: bodyBytes) | |
let bodyDigest = Data(digest).base64EncodedString() | |
// ISO UTC Timestamp fot eh date header | |
let dateFormatter = DateFormatter() | |
dateFormatter.dateFormat = "E, dd MMM yyyy HH:mm:ss z" | |
dateFormatter.timeZone = TimeZone(abbreviation: "UTC") | |
let date = dateFormatter.string(from: Date()) | |
// HMAC for the Authorization header | |
let stringToSign = "POST\n\(url.path)?\(url.query!)\n\(date);\(url.host!);\(bodyDigest)" | |
let key = SymmetricKey.init(data: Data(base64Encoded: accessKey)!) | |
let code = HMAC<SHA256>.authenticationCode(for: stringToSign.data(using: .utf8)!, using: key) | |
let authHeader = "HMAC-SHA256 SignedHeaders=date;host;x-ms-content-sha256&Signature=\(Data(code).base64EncodedString())" | |
// configure the URL request | |
var request = URLRequest(url: url) | |
request.httpMethod = "POST" //set http method as POST | |
request.httpBody = bodyBytes | |
request.addValue("application/json", forHTTPHeaderField: "Content-Type") | |
request.addValue(date, forHTTPHeaderField: "Date") | |
request.addValue(bodyDigest, forHTTPHeaderField: "x-ms-content-sha256") | |
request.addValue(authHeader, forHTTPHeaderField: "Authorization") | |
// submit the HTTP request | |
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in | |
if let error = error { | |
completionHandler(.failure(error)) | |
return | |
} | |
let decoder = JSONDecoder() | |
let result = try! decoder.decode(FetchTokenResult.self, from: data!) | |
completionHandler(.success(result)) | |
} | |
task.resume() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment