iOS - Security Module
To provide security validation before authentication, a proper implementation of the
SecurityModule protocol is required. Q2MobileCore will interact with your
module to determine whether login operations should be allowed based on security policies.
The SecurityModule interface is used when creating a module that needs to
perform security checks before allowing user authentication. This module provides
security validation to ensure device integrity and prevent unauthorized access.
Security Validation
The module performs security checks for the following scenarios:
- Device integrity verification
- App tampering detection
- Security policy compliance
- Custom security rule validation
Implementation
Implementing a SecurityModule is straightforward—create a class conforming to the
SecurityModule protocol requirements.
/// Represents the result of a security check operation.
public enum SecurityResult {
/// Indicates that the security check passed and the operation is allowed.
case allow
/// Indicates that the security check failed with an associated error message.
case deny(String)
}
/// A type that can provide any module to check in for security rules.
/// This protocol defines the interface for modules that perform security validations
/// before allowing certain operations like user login.
/// **Note:** All methods in this protocol have default implementations that return `.allow`.
/// Modules should override these methods to implement custom security validation logic.
public protocol SecurityModule: Module {
/// Determines if login should be allowed based on security rules.
/// This method performs various security checks such as device integrity,
/// app tampering detection, or other security policies defined by the module.
/// - Returns: SecurityResult indicating whether login is allowed or denied with reason
/// - Note: Default implementation returns `.allow`. Override to implement custom login security checks.
func allowLogin() -> SecurityResult
/// Determines if the device meets security requirements.
/// This method performs device-level security checks such as jailbreak detection,
/// device integrity validation, or other device-specific security policies.
///
/// - Returns: SecurityResult indicating whether the device is secure (allowed) or denied with reason
/// - Note: Default implementation returns `.allow`. Override to implement custom device security checks.
func isDeviceSecure() -> SecurityResult
}
import Q2ModuleInterfaces
extension Q2MySecurityModule: SecurityModule {
public func allowLogin() -> SecurityResult {
let deviceSecurityResult = isDeviceSecure()
switch deviceSecurityResult {
case .allow:
return .allow
case .deny(let reason):
return .deny("Login blocked: \(reason)")
}
}
public func isDeviceSecure() -> SecurityResult {
// Perform device security checks (jailbreak detection, integrity validation, etc.)
if performDeviceSecurityCheck() {
return .allow
} else {
return .deny("Device security validation failed")
}
}
private func performDeviceSecurityCheck() -> Bool {
// Custom device security logic implementation
return true // Replace with actual security check logic
}
}
Behind the Scene
When user is going to be logged in using Password Authentication or SSO
Authentication, module implementing this interface would be asked whether device is
secured or not. If it returns .deny(String), then user's authentication would be blocked
and provided message would be presented to user in respective authentication UI.
Security Module Behavior
-
No Security Module: When no security module is implemented, no validation occurs and authentication proceeds normally.
-
Multiple Security Modules: When multiple security modules exist from different providers:
- All modules are evaluated for security validation
- If any module returns
.deny(String), the overall result is considered denied - Authentication is blocked if any module reports a security violation
- Only when all modules return
.allowwill authentication be allowed
Default Implementation
/// Default implementation for SecurityModule
/// All methods return `.allow` by default to ensure safe fallback behavior.
public extension SecurityModule {
/// Default implementation that allows the operation.
/// Modules can override this method to implement custom login security checks.
/// - Returns: SecurityResult.allow by default
func allowLogin() -> SecurityResult {
return .allow
}
/// Default implementation that allows the operation.
/// Modules can override this method to implement custom device security checks.
/// - Returns: SecurityResult.allow by default
func isDeviceSecure() -> SecurityResult {
return .allow
}
}