Authentication Hub Core iOS-SDK - 2.3.2
Authentication Hub Core SDK - 2.3.2 includes Authentication Hub Request Module, Password Encryption Module, Network Module, and Utility APIs.
Updates in Authentication Hub Core iOS 2.3.2 release
VIP Authentication Hub
includes the following new features and improvements in iOS SDK 2.3.2 release:- Introduced a new SDK API, "getFieldsToBeEncryptedInAuthFlow()", which returns the list of the fields that require encryption by the SDK during communication with the Authentication Hub server. For more information, see Getting the list of fields to be encrypted in the authentication flow, and Support for proxy URL configuration to get the list of fields that are required for encryption .
- The Branding Settings related SDK API calls and Network request object initialization SDK API call has been refactored. See Initiate Authentication .
- Following this release, the network request object can be set to the AHCore instance object using thesetAuthHubRequestObject()SDK API. See Setting Up the Network Request Object .
If you previously used the
initAuth
SDK API to set the request object for logging network request data, you now must set the Authentication Hub request object by invoking the setAuthHubRequestObject() SDK API on the AHCore instance.AuthHubCore.xcframework APIs and Integration Flow
This section includes the following sub-sections:
Authentication Hub Network Request Module
Authentication Hub Network Request Module
Authentication Hub Network Request Module is a part of the AuthHubCore framework. The Authentication Hub Client SDK APIs are designed to handle the network request and response for all the Authentication Hub APIs, such as, "/authentication", "/BrandingSettings" and have complete control over them. Apart from handling essential API request payload/headers/query params, if you intend to customize the network layer to use it for tasks like adding custom headers or supporting SSL pinning, you need to implement three interfaces in your application to handle the network request customization. These interfaces are provided by Authentication Hub and are explained in the following sections:
- : This interface provides the set of APIs that mobile applications can implement to customize the network request. Using these API implementation, the mobile application can override the headers, add custom headers, or add new parameters to the request payload as required.AuthHubEndPointThis interface defines the following APIs -
The following table explains the APIs of this interface:func setRequestPayloadParameters(_ params: [String: Any]!) func setRequestHeaders(_ headers: [String: Any]!) func build() throws -> URLRequestAPI NameDescriptionsetRequestPayloadParameters()Accepts the map of key-value pairs which is sent in the JSON request body of the network request.setRequestHeaders()Accepts the map of key-value pairs which is sent as a request header of the network request.build()Builds an actual network request object which is sent to the Authentication Hub server. - : This interface provides the APIs required for logging the network level data and logs the time that is required for the network calls. The AuthHubRequestLogger provides the ability to log network request level information, such as request headers, request body, request response body, and response time.AuthHubRequestLoggerThis interface defines the following APIs -The AuthHubRequestLogger interface must be implemented if you want to add custom logging to the network request object.
The following table explains the APIs of this interface:func enableLog(enable: Bool) func setLoggingType(type: RequestLoggingType) func logRequestData(responseTime: Int64, endPoint: AuthHubEndpoint, respDict: [String : AnyObject]?)API NameDescriptionenableLog()Enables logging for a network request. By default it is.disabledsetLoggingType()Sets the logging type of the request logger. The RequestLoggingType is anthat can have these values:enum,resp_time, anddata.none- resp_time - This type of logger logs only the response time
- data - This type of logger logs the request data, such as, headers, request body, response body and response time
- none - This type of logger does not log any data
logRequestData()This API is used for logging the request data as per the RequestLoggingType.- :This class is the default implementation of the AuthHubRequestLogger interface. By default, this class logs all request data to the console.AHRequestLoggerYou must create an instance of this class and must initialize it with the name of the log file, if you want the logger to write logs to the file.
- : This interface provides the APIs required to handle network level functionality, such as, sending requests, logging network request. This interface defines the following APIs -AHAPIRequest
The following table explains the APIs of this interface:func sendRequest(endpoint: AuthHubEndpoint) async throws -> AHRequestResult func setRequestLogger(requestLogger: AuthHubRequestLogger)API NameDescriptionsendRequest()This API accepts the AuthHubEndpoint instance object.setRequestLogger()This API sets the AuthHubRequestLogger object for the network request object.- : This class is the default implementation of theAuthHubBasicRequestinterface.AHAPIRequest
The following example shows a sample implementation of the network request interface that is defined previously.
import Foundation import AuthHubCore class SampleAuthHubRequest : AuthHubBasicRequest { func addRequestHeaders(endpoint: AuthHubEndpoint) -> [String:Any] { let urlPath = endpoint.path var newHeaders = endpoint.headers switch(urlPath) { case .brandingSettings: newHeaders["HEDMORAL_BRANDING_SETTINGS"] = "HEDMORAL_BRANDING_VALUE"; break; case .authHubPublicKey: newHeaders["HEDMORAL_PUBLIC_KEY"] = "HEDMORAL_PUBLIC_KEY_VALUE"; break; case .serverNonceGenerator: newHeaders["HEDMORAL_SERVER_NONCE"] = "HEDMORAL_SERVER_NONCE_VALUE"; break; case .authEndpoint: newHeaders["HEDMORAL_INIT_AUTH"] = "HEDMORAL_INIT_AUTH_VALUE"; break; case .registerChallengeGenerator: newHeaders["HEDMORAL_REG_CHAL_GEN"] = "HEDMORAL_REG_CHAL_GEN_VALUE"; break; case .registerChallengeVerifier: newHeaders["HEDMORAL_REG_CHAL_VERIFY"] = "HEDMORAL_REG_CHAL_VERIFY_VALUE"; break; case .authChallengeGenerator: newHeaders["HEDMORAL_AUTH_CHAL_GEN"] = "HEDMORAL_AUTH_CHAL_GEN_VALUE"; break; case .authChallengeVerifier: newHeaders["HEDMORAL_AUTH_CHAL_VERIFY"] = "HEDMORAL_AUTH_CHAL_VERIFY_VALUE"; break; case .txnSignChallengeGenerator: newHeaders["HEDMORAL_TXN_CHAL_GEN"] = "HEDMORAL_TXN_CHAL_GEN_VALUE"; break; case .txnSignChallengeVerifier: newHeaders["HEDMORAL_TXN_CHAL_VERIFY"] = "HEDMORAL_AUTH_CHAL_VERIFY_VALUE"; break; @unknown default: newHeaders["HEDMORAL_DEFAULT_HEADER"] = "HEDMORAL_DEFAULT_HEADER_VALUE"; break; } return newHeaders; } override func sendRequest(endpoint: AuthHubEndpoint) async throws -> AHRequestResult { let newHeaders = addRequestHeaders(endpoint: endpoint) endpoint.setRequestHeaders(newHeaders) return try await super.sendRequest(endpoint: endpoint) } }
The following example shows how to use the sample request that was created in the previous example to initialize the Authentication Hub FIDO SDK instance:
let ahfidosdk = AHFIDOSDK.getInstance() /*Create instance of SampleAuthHubRequest*/ let hedmoralRequestObject = SampleAuthHubRequest() /*Create instance of AHRequestLogger and enable it*/ let ahReqLogger = AuthHubCore.AHRequestLogger(fileName: nil) ahReqLogger.enableLog(enable: true) /*Set request logger for created request object*/ hedmoralRequestObject.setRequestLogger(requestLogger: ahReqLogger) /*Create instance of AHRequestLogger and enable it*/ ahfidosdk.initFIDO(serverHost: "example.broadcom.com", tenant: "default", authhubRequest: hedmoralRequestObject)
Authentication Hub Core Framework APIs
This section includes the Authentication Hub Core Framework APIs:
Create an instance of the AuthHubCore.framework AHCore class
- To create an instance of theAuthHubCore.framework AHCoreclass, invoke thegetInstance()API. The API returns a singleton instance of the AHCore class.public static func getInstance() -> AHCore
- To get the version of theAuthHubCore.framework,invoke thegetVersion() API.The currently supported version of theAuthHubCore.frameworkis 2.3.2.public static func getVersion() -> String
Setting Up the Network Request Object
To set the network request object, call the AuthHubCore API,
setAuthHubRequestObject()
public func setAuthHubRequestObject(authhubRequest: AuthHubBasicRequest)
The API parameters have been described in the following table:
Name | Type | Description |
authhubRequest | AuthHubBasicRequest | This is an optional parameter and can be set to nil value.
As a developer, if you intend to customise the network request which is being sent to Authentication Hub (like adding custom header or additional request body param), then implement AHAPIRequest interface. The AuthHubBasicRequest class is the default implementation of the AHAPIRequest interface. When the initAuth() is invoked with authhubRequest as nil object, then SDK makes use of default implementation of AHAPIRequest interface that is; AuthHubBasicRequest. |
Initiate Authentication
- Use theinitAuthfunction to initiate the authentication flow by invoking the POSThttps://<sspHost>/<tenantName>/auth/v1/authenticateAPI. Use this function at all existing places where you are invoking the/authenticateAPI.API Signaturepublic func initAuth(serverHost: String, tenant: String, requestHeaders:[String:Any], authRequestParams: [String:Any], fieldsTobeEncryptedList:[String]?, completionBlock: @escaping (( _ response: AHCoreResult) -> Void)) throwsThe API parameters are described in the following table:NameTypeDescriptionserverHoststringThis is the Authentication Hub server host.tenantstringThis is the tenant name.requestHeadersdictionaryThe requestHeaders is the collection of Authentication Hub FIDO Server specific headers that are required for REST API calls.The following parameters should be passed with proper values:
- Authorization
authRequestParamsdictionaryThis is a collection of parameters that are required for '/authenticate' REST API calls. The following sample parameters can be passed as a dictionary object:{ "subject": "{{userLoginid}}", "channel": "mobile", "ipAddress": "10.10.123.124", "action":"authenticate", "rememberMe" : true, "device": { "signature": { "iaAuthData": "_v02MyUgNGgYOi88OTk0emB7ZXV9GDQ2PDshOiY9bnUcOyEwOXUYNDZ1GgZ1DXVkZQpkYApjfHUUJSU5MAIwNx48IXpgZmJ7ZmN1fR4dARgZeXU5PD4wdRIwNj46fHUWPSc6ODB6bWB7ZXthZG1me21mdQY0MzQnPHpgZmJ7ZmMpGDQ2HDshMDlzMyUmNmhmZSlkY21lKWRlYGUpZGNtZSlsYWxzMyUmImg8OyEwJzs0OXglMTN4IzwwIjAnKTg9PzM3ODEyNjM/NzclNDA6PzozOj06MDMyPDA9PzQ8KTw7ITAnOzQ5eDs0Njl4JTkgMjw7czMlJTxoczMlIS9oYHtgczMlOTtoMDt4EhcpKSlzMyU2JWhlZGRkZWRkZGRkZGRkZGRkZGRkZGRkZWRkZGRkZGRkZGRkZGVkZGRkZWRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGVkZXMzJSM2aHMzJSMmaGdzMyUhJmhzMyUhMmg=" } } }fieldsTobeEncryptedListstringarray- This is optional parameter and can be set to nil value.
- The list of string array contains the list of the fields which needs encryption. This list of fields can be obtained from getFieldsToBeEncryptedInAuthFlow() API. The list of fields that are sent to initAuth() decides whether server nonce is required to encrypt field in the transit.
completionBlockclosure blockRepresents the closure block that the SDK passes to the calling API. The closure block returns the AHCoreResult object as a response. AHCoreResult is a struct object containing data (dictionary object), code (API response), and message (string) as members.The completionBlock closure returns a AHCoreResult struct object as defined here:public struct AHCoreResult { public init(code: Int, message: String, data: [String:Any]) { self.code = code self.message = message self.data = data } public var code : Int public var message : String public var data : [String:Any] } - Example: API call with Server Host and Tenant
This function is used for initiating the authentication flow by invoking the POSTdo { //set network request object in AuthCore ahCore.setAuthHubRequestObject(authhubRequest:hedmoralRequestObject) //get access token from server var jsonResponse = getAccessTokenFromAHServer() var accessToken = "Bearer \(jsonResponse["access_token"] as! String)" var reqHeaders = [String:Any]() reqHeaders["Authorization"] = accessToken /*get list of the fields from BrandingSettings API*/ let brandingSettingsHeaders:[String:String] = [AHConstants.HttpHeader.KeyAz:accessToken] try ahCore.getFieldsToBeEncryptedInAuthFlow(serverHost: serverHost, tenant: tenant, requestHeaders:brandingSettingsHeaders) { result in if(result.code == AHResult.Code.SUCCESS) { //On success, fetch the list of the fields which needs encryption let fieldsToBeEncrypted = result.data[AHConstants.GenericKeys.FieldsToBeEncrypted] as? [String] ?? [] //pass on the list to initAuth() try ahCore.initAuth(serverHost: serverHost, tenant: tenant, requestHeaders: reqHeaders, authRequestParams: paramBodyRequest, fieldsTobeEncryptedList:fieldsToBeEncrypted) { response in if response.data["errorCode"] != nil { let errorCode = response.data["errorCode"] as! String let code = Int(errorCode)! var errorMsg = response.data["errorMessage"] as? String ?? "" if(!errorMsg.isEmpty) { print("Error: message - \(errorMsg) and code: \(errorCode)") } } else { if let flowState = response.data["flowState"] as? String { print(flowState) } guard let nextAction = response.data["nextaction"] else { Logger().logMessage(message: "Next Action not set!!") return } //handle nevigation to next page based on response from AH server navigateToNextPageBasedOnNextAction() } } } }https://<proxyUrl>/auth/v1/authenticateAPI. This API also supports theproxy URLconfiguration for the Authentication Hub instance where the tenant name is not required as part of the URL. This function should be used at all the existing places where you are invoking the/authenticateAPI.API Signature
The API parameters have been described here:public func initAuth(serverUrl: String, requestHeaders:[String:Any], authRequestParams: [String:Any], fieldsTobeEncryptedList:[String]?, completionBlock: @escaping (( _ response: AHCoreResult) -> Void)) throwsNameTypeDescriptionserverURLstringThe endpoint url that can be a proxy url for an Authentication Hub instance.requestHeadersdictionaryThe requestHeaders is the collection of Authentication Hub FIDO Server specific headers that are required for REST API calls.The following parameters should be passed with proper values:- Authorization
authRequestParamsdictionaryThis is a collection of parameters that are required for '/authenticate' REST API calls. The following sample parameters can be passed as a dictionary object:{ "subject": "{{userLoginid}}", "channel": "mobile", "ipAddress": "10.10.123.124", "action":"authenticate", "rememberMe" : true, "device": { "signature": { "iaAuthData": "_v02MyUgNGgYOi88OTk0emB7ZXV9GDQ2PDshOiY9bnUcOyEwOXUYNDZ1GgZ1DXVkZQpkYApjfHUUJSU5MAIwNx48IXpgZmJ7ZmN1fR4dARgZeXU5PD4wdRIwNj46fHUWPSc6ODB6bWB7ZXthZG1me21mdQY0MzQnPHpgZmJ7ZmMpGDQ2HDshMDlzMyUmNmhmZSlkY21lKWRlYGUpZGNtZSlsYWxzMyUmImg8OyEwJzs0OXglMTN4IzwwIjAnKTg9PzM3ODEyNjM/NzclNDA6PzozOj06MDMyPDA9PzQ8KTw7ITAnOzQ5eDs0Njl4JTkgMjw7czMlJTxoczMlIS9oYHtgczMlOTtoMDt4EhcpKSlzMyU2JWhlZGRkZWRkZGRkZGRkZGRkZGRkZGRkZWRkZGRkZGRkZGRkZGVkZGRkZWRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGVkZXMzJSM2aHMzJSMmaGdzMyUhJmhzMyUhMmg=" } } }fieldsTobeEncryptedListstringarray- This is an optional parameter and can be set to nil.
- The list of string array contains the list of the fields which needs encryption. This list of fields can be obtained from getFieldsToBeEncryptedInAuthFlow() API. The list of fields sent to initAuth() decides whether server nonce is required to encrypt the fields in the transit.
completionBlockclosure blockRepresents the closure block that the SDK passes to the calling API. The closure block returns the AHCoreResult object as a response. AHCoreResult is a struct object containing data (dictionary object), code (API response), and message (string) as members.The completionBlock closure returns a AHCoreResult struct object as defined here:public struct AHCoreResult { public init(code: Int, message: String, data: [String:Any]) { self.code = code self.message = message self.data = data } public var code : Int public var message : String public var data : [String:Any] } - Example: API call with Proxy URLdo { //set network request object in AuthCore ahCore.setAuthHubRequestObject(authhubRequest:hedmoralRequestObject) //get access token from server var jsonResponse = getAccessTokenFromAHServer() var accessToken = "Bearer \(jsonResponse["access_token"] as! String)" var reqHeaders = [String:Any]() reqHeaders["Authorization"] = accessToken /*get list of the fields from BrandingSettings API*/ let brandingSettingsHeaders:[String:String] = [AHConstants.HttpHeader.KeyAz:accessToken] try ahCore.getFieldsToBeEncryptedInAuthFlow(serverUrl: proxyUrl, requestHeaders:brandingSettingsHeaders) { result in if(result.code == AHResult.Code.SUCCESS) { //On success, fetch the list of the fields which needs encryption let fieldsToBeEncrypted = result.data[AHConstants.GenericKeys.FieldsToBeEncrypted] as? [String] ?? [] //pass on the list to initAuth() try ahCore.initAuth(serverUrl: proxyUrl, requestHeaders: reqHeaders, authRequestParams: paramBodyRequest, fieldsTobeEncryptedList:fieldsToBeEncrypted) { response in if response.data["errorCode"] != nil { let errorCode = response.data["errorCode"] as! String let code = Int(errorCode)! var errorMsg = response.data["errorMessage"] as? String ?? "" if(!errorMsg.isEmpty) { print("Error: message - \(errorMsg) and code: \(errorCode)") } } else { if let flowState = response.data["flowState"] as? String { print(flowState) } guard let nextAction = response.data["nextaction"] else { Logger().logMessage(message: "Next Action not set!!") return } //handle nevigation to next page based on response from AH server navigateToNextPageBasedOnNextAction() } } } }
Data Encryption
Authentication Hub supports "Password" (In-Transit and At-Rest) encryption and "Device Signature" (In-Transit) encryption.
Prerequisite
To use the iOS client SDK for and encryption, the following prerequisites must be met.
"Password"
"Device Signature"
- Change the value of the tenant setting,fieldsToBeEncryptedInAuthFlowto"Password", and/or "Device Signature".The default value isnone,which indicates that "Password" and "Device Signature" encryption is disabled by default.[ { "name": "fieldsToBeEncryptedInAuthFlow", "value": "password, devicesignature" } ]
- Integrate theAuthHubCore.frameworkSDK with the iOS application. The SDK includes the APIs that can be called from the iOS application context to achieve "Password" and "Device Signature" encryption.TheAuthHubCore.frameworkSDK file can be found in the VIP Authentication Hub - Customer Validation site along with other SDKs.
Get the list of fields to be encrypted in the authentication flow
- To get a list of the fields that are enabled for encryption, invokegetFieldsToBeEncryptedInAuthFlow()function before calling initAuth().
The API parameters have been described here:public func getFieldsToBeEncryptedInAuthFlow(serverHost: String, tenant: String, requestHeaders:[String:Any], completionBlock: @escaping ( _ response: AHCoreResult) -> Void) throwsNameTypeDescriptionserverHoststringThis is the Authentication Hub server host.tenantstringThis is the tenant name.requestHeadersdictionary- The requestHeaders is the collection of Authentication Hub FIDO Server specific headers that are required for for "/auth/v1/BrandingSettings" Authentication Hub REST API calls.
- In this case, you must pass authorization request header value as reqHeaders["Authorization"] = accessToken as mandatory request header parameter.
- Other optional custom headers can be passed as per customer requirement.
completionBlockclosure block- Represents the closure block that the SDK passes to the calling API. The closure block returns the AHCoreResult object as a response. AHCoreResult is a struct object containing data (dictionary object), code (API response), and message (string) as members.
- The data is a dictionary object, message is a string, and the code is the API response code.
- The result.data[AHConstants.GenericKeys.FieldsToBeEncrypted] contains list of fields(string array) [String] which can be passed on to the initAuth() API
The completionBlock closure returns an AHCoreResult object, containing a dictionary collection named "data." The result.data dictionary, comprises a key identified as AHConstants.GenericKeys.FieldsToBeEncrypted (specified in the fieldName argument of the API) and a list of fields in string array format. [String], denoting the fields requiring encryption. Currently, it may include "password," "devicesignature," or both.
do { //set network request object in AuthCore ahCore.setAuthHubRequestObject(authhubRequest:hedmoralRequestObject) //get access token from server var jsonResponse = getAccessTokenFromAHServer() var accessToken = "Bearer \(jsonResponse["access_token"] as! String)" var reqHeaders = [String:Any]() reqHeaders["Authorization"] = accessToken /*get list of the fields from BrandingSettings API*/ let brandingSettingsHeaders:[String:String] = [AHConstants.HttpHeader.KeyAz:accessToken] try ahCore.getFieldsToBeEncryptedInAuthFlow(serverHost: serverHost, tenant: tenant, requestHeaders:brandingSettingsHeaders) { result in if(result.code == AHResult.Code.SUCCESS) { //On success, fetch the list of the fields which needs encryption let fieldsToBeEncrypted = result.data[AHConstants.GenericKeys.FieldsToBeEncrypted] as? [String] ?? [] //pass on the list to initAuth() try ahCore.initAuth(serverHost: serverHost, tenant: tenant, requestHeaders: reqHeaders, authRequestParams: paramBodyRequest, fieldsTobeEncryptedList:fieldsToBeEncrypted) { response in if response.data["errorCode"] != nil { let errorCode = response.data["errorCode"] as! String let code = Int(errorCode)! var errorMsg = response.data["errorMessage"] as? String ?? "" if(!errorMsg.isEmpty) { print("Error: message - \(errorMsg) and code: \(errorCode)") } } else { if let flowState = response.data["flowState"] as? String { print(flowState) } guard let nextAction = response.data["nextaction"] else { Logger().logMessage(message: "Next Action not set!!") return } //handle nevigation to next page based on response from AH server navigateToNextPageBasedOnNextAction() } } } }
Support for proxy URL configuration to get the list of fields that are required for encryption
The following API supports the proxy Url configuration for Authentication Hub instance where tenant name is not required as part of the URL.
The API parameters have been described here:public func getFieldsToBeEncryptedInAuthFlow(serverUrl: String, requestHeaders:[String:Any], completionBlock: @escaping ( _ response: AHCoreResult) -> Void) throws
Name | Type | Description |
serverURL | string | The endpoint url that can be a proxy url for an Authentication Hub instance. |
requestHeaders | dictionary |
|
completionBlock | closure block |
|
The completionBlock closure returns an AHCoreResult object, containing a dictionary collection named "data." The result.data dictionary, comprises a key identified as AHConstants.GenericKeys.FieldsToBeEncrypted (specified in the fieldName argument of the API) and a list of fields in string array format. [String], denoting the fields requiring encryption. Currently, it may include "password," "devicesignature," or both, as shown in the following example.
do { //set network request object in AuthCore ahCore.setAuthHubRequestObject(authhubRequest:hedmoralRequestObject) //get access token from server var jsonResponse = getAccessTokenFromAHServer() var accessToken = "Bearer \(jsonResponse["access_token"] as! String)" var reqHeaders = [String:Any]() reqHeaders["Authorization"] = accessToken /*get list of the fields from BrandingSettings API*/ let brandingSettingsHeaders:[String:String] = [AHConstants.HttpHeader.KeyAz:accessToken] try ahCore.getFieldsToBeEncryptedInAuthFlow(serverUrl: proxyUrl, requestHeaders:brandingSettingsHeaders) { result in if(result.code == AHResult.Code.SUCCESS) { //On success, fetch the list of the fields which needs encryption let fieldsToBeEncrypted = result.data[AHConstants.GenericKeys.FieldsToBeEncrypted] as? [String] ?? [] //pass on the list to initAuth() try ahCore.initAuth(serverUrl: proxyUrl, requestHeaders: reqHeaders, authRequestParams: paramBodyRequest, fieldsTobeEncryptedList:fieldsToBeEncrypted) { response in if response.data["errorCode"] != nil { let errorCode = response.data["errorCode"] as! String let code = Int(errorCode)! var errorMsg = response.data["errorMessage"] as? String ?? "" if(!errorMsg.isEmpty) { print("Error: message - \(errorMsg) and code: \(errorCode)") } } else { if let flowState = response.data["flowState"] as? String { print(flowState) } guard let nextAction = response.data["nextaction"] else { Logger().logMessage(message: "Next Action not set!!") return } //handle nevigation to next page based on response from AH server navigateToNextPageBasedOnNextAction() } } } }
Encryption Confirmation
Encryption confirmation for "Password" and "Device Signature" is described in this section.
- "Password" Encryption ConfirmationCall theisEncryptionRequiredForFieldfunction to check if the password field is configured for "Password" encryption.API Signaturepublic func isEncryptionRequiredForField(serverHost: String, tenant: String, requestHeaders:[String:Any], fieldName:String, completionBlock: @escaping (( _ response: AHCoreResult) -> Void)) throws -> BoolSample Code for "Password" Encryption//get access token from server var jsonResponse = getAccessTokenFromAHServer() var accessToken = "Bearer \(jsonResponse["access_token"] as! String)" var reqHeaders = [String:Any]() reqHeaders["Authorization"] = accessToken let ahCore = AHCore.getInstance()do { //get user password try ahCore.isEncryptionRequiredForField(serverHost: serverHost, tenant: tenant, requestHeaders:reqHeaders, fieldName: "password", completionBlock: { result in if result.data["errorCode"] != nil { let errorCode = result.data["errorCode"] as! String let code = Int(errorCode)! var errorMsg = result.data["errorMessage"] as? String ?? "" if(!errorMsg.isEmpty) { print("Error: message - \(errorMsg) and code: \(errorCode)") } handleError(errorCode, errorMsg) } do { let code = result.code let isPswdEncRequired = result.data[AHConstants.GenericKeys.PasswordField] as? Bool ?? false if(code == AHResult.Code.SUCCESS && isPswdEncRequired) { let encryptedPassword = try ahCore.encryptdData(plainText: password) if(!encryptedPassword.isEmpty) { password = encryptedPassword } } //send password authentication request to the Authentication Hub server performPasswordAuthentication(password) } catch { print(error) return } }) } catch { let message = error.localizedDescription print("Error: message - \(message)") }
- "Device Signature" Encryption ConfirmationCall theisEncryptionRequiredForFieldfunction to check if the device signature field is configured for encryption.API Signaturepublic func isEncryptionRequiredForField(serverHost: String, tenant: String, requestHeaders:[String:Any], fieldName:String, completionBlock: @escaping (( _ response: AHCoreResult) -> Void)) throws -> BoolSample Code for "Device Signature" Encryption//get access token from server var jsonResponse = getAccessTokenFromAHServer() var accessToken = "Bearer \(jsonResponse["access_token"] as! String)" var reqHeaders = [String:Any]() reqHeaders["Authorization"] = accessToken let ahCore = AHCore.getInstance()do { //get device signature from VIPIA framework try ahCore.isEncryptionRequiredForField(serverHost: serverHost, tenant: tenant, requestHeaders:reqHeaders, fieldName: "devicesignature", completionBlock: { result in if result.data["errorCode"] != nil { let errorCode = result.data["errorCode"] as! String let code = Int(errorCode)! var errorMsg = result.data["errorMessage"] as? String ?? "" if(!errorMsg.isEmpty) { print("Error: message - \(errorMsg) and code: \(errorCode)") } handleError(errorCode, errorMsg) } do { let code = result.code let isEncRequired = result.data["devicesignature"] as? Bool ?? false if(code == AHResult.Code.SUCCESS && isEncRequired) { let encryptedSignature = try ahCore.encryptdData(plainText: deviceSignature) if(!encryptedSignature.isEmpty) { deviceSignature = encryptedSignature } } //send encrypted device signature as "x-device-tag" header to the Authentication Hub server setEcryptedDeviceTagHeader(deviceSignature) } catch { print(error) return } }) } catch { let message = error.localizedDescription print("Error: message - \(message)") }
Support for proxy URL configuration
proxy URL
configuration The Encryption API also supports the
proxy URL
configuration for the AuthHub instance where the tenant name is not required as part of the URL. The following is an example for "Password" encryption. You can use the same API signature for "Device Signature".
API Signature
public func isEncryptionRequiredForField(serverUrl: String, requestHeaders:[String:Any] fieldName:String, completionBlock: @escaping (( _ response: AHCoreResult) -> Void)) throws -> Bool
Sample Code
//get access token from server var jsonResponse = getAccessTokenFromAHServer() var accessToken = "Bearer \(jsonResponse["access_token"] as! String)" var reqHeaders = [String:Any]() reqHeaders["Authorization"] = accessToken let ahCore = AHCore.getInstance() do { //get user password try ahCore.isEncryptionRequiredForField(serverUrl: proxyUrl, requestHeaders:reqHeaders, fieldName: "password", completionBlock: { result in if result.data["errorCode"] != nil { let errorCode = result.data["errorCode"] as! String let code = Int(errorCode)! var errorMsg = result.data["errorMessage"] as? String ?? "" if(!errorMsg.isEmpty) { print("Error: message - \(errorMsg) and code: \(errorCode)") } handleError(errorCode, errorMsg) } do { let code = result.code let isPswdEncRequired = result.data[AHConstants.GenericKeys.PasswordField] as? Bool ?? false if(code == AHResult.Code.SUCCESS && isPswdEncRequired) { let encryptedPassword = try ahCore.encryptdData(plainText: password) if(!encryptedPassword.isEmpty) { password = encryptedPassword } } //send password authentication request to AH server performPasswordAuthentication(password) } catch { print(error) return } }) } catch { let message = error.localizedDescription print("Error: message - \(message)") }
Parameter Description
- hostName:Specifies the SSP (VIP Authentication Hub) server hostname. Data Type -string.
- tenant:Specifies the tenant name. Example: default. Data Type -string.
- serverUrl:Specifies the endpoint URL that can be a proxy URL for an Authentication Hub instance. Data Type -string.Ensure that the proxy resolves the Authentication Hub instance URL that points to the intendedAuthentication Hubserver host and tenant.
- requestHeaders:Represents a collection ofVIP Authentication Hubserver-specific headers that are required for the REST API calls. The mandatory parameter to be passed is the Authorization header containing"Bearer <auth_token>".Data Type -dictionary.
- fieldName:Specifies the field name that is marked for password encryption. The value of this parameter must bepassword.
- completionBlock:Represents the closure block that the SDK passes to the calling API. The closure block returns the AHCoreResult object as a response. AHCoreResult is a struct object containing data (dictionary object), code (API response), and message (string) as members. The result.data dictionary contains the key as the field name (password) and boolean data (true, false) as a value. The valuetrueindicates that the password field must be encrypted.
Encrypt "Password" and "Device Signature"
- Encrypt PasswordTo encrypt the plain password with the tenant-level public keywithoutserver nonce, call theencryptDataWithPublicKeyfunction:API Signaturepublic func encryptDataWithPublicKey(plainText: String) throws -> StringTo encrypt the plain password with the tenant-level public keyalong withserver nonce, call theencryptDatafunction:API Signaturepublic func encryptData(plainText: String) throws -> StringParameter Description
- plainText:Specifies the password string that must be encrypted in the authentication flow.
API ResponseThe API encrypts the plain text and returns the encrypted value as a base64 encoded string. The encrypted password can be sent to theVIP Authentication Hubwhere password encryption is enabled for authentication. For server-side information, see Password Encryption.
- Encrypt "Device Signature"To encrypt the plain "Device Signature" with symmetric key, call theencryptDataWithSymmetricKeyfunction:API Signaturepublic func encryptDataWithSymmetricKey(plainText: String) throws -> StringParameter Description
- plainText:Specifies the "Device Signature", "X-Device-Tag" string that must be encrypted in the authentication flow.
API ResponseThe API encrypts the plain text and returns the encrypted value in a base64 encoded string. The encrypted device signature and x-device-tag can be sent to theVIP Authentication Hubas an encrypted data. For server-side information, see "Device Signature" Encryption.