Developer

Logon Screen Configuration Options

To change the behavior of MAFLogonManagerNG, adjust the feature and default values configuration files at build time. The plist format configuration files are located in the MAFLogonManagerNG.bundle folder. plist is an XML format you can adjust using in Xcode or any text editor.

Feature Configuration

To change the behavior of the component, adjust the MAFLogonManagerOptions.plist file, which is in the MAFLogonManagerNG bundle folder in your project.

Key Value Type Description Default Value
keyMAFUrlSchemeForAfaria String Changes the default URL scheme of the Afaria application. EMPTY
keyMAFUseAfaria BOOL Determines whether to use Afaria.

NO - the Afaria client application is not called, even if it is present on the iOS device.

YES - Afaria client application is always called.

NO (false)

You can also declare resources with the MAFLogonUIOptions.plist feature configuration, which is in the MAFLogonUING bundle.

Key Value Type Description Default Value
keyMAFLogonUseFlowMode BOOL YES - Logon Core tries to find a suitable communicator implementation for the infrastructure used. It analyses the input provided by the user and triggers test requests to various onboarding scenarios. YES
keyMAFLogonAllowAutomaticSecureStoreCreation BOOL Whether to allow the secure store to be automatically created.

NO - create the secure store should before the logon component is initialized.

YES
keyMAFLogonUseSplashScreen BOOL Determines whether to present splash screen when logon operation is called for the first time. YES
keyMAFLogonOperationContextHideRegistrationFields BOOL Defines which fields to show on the resgistratoin screen. Multiple values

Default Values Configuration

The MAFLogonManagerNG.bundle folder contains the MAFLogonOperationContextDefaultValues.plist file, which declares the configuration structure. The plist defines the keys that are used to set default values for the logon scenarios. keyMAFLogonOperationContextDefaultValues is the main key in the default values dictionary. The only screen that supports default values is the registration screen.You can set the default values for the registration screen in the idMAFLogonOperationContextTypeRegister key. Use these keys to set default values for the individual input fields:
Key Value Type Description Default Value
keyMAFLogonOperationContextServerPortNonSecure Number Nonsecure port 8080
keyMAFLogonOperationContextServerPortSecure Number Secure port 8081
keyMAFLogonOperationContextServerHost String Server host name without protocol or port or suffixes EMPTY
keyMAFLogonOperationContextServerPort Number Server port EMPTY
keyMAFLogonOperationContextIsHttps BOOL Whether to use secure channel YES
keyMAFLogonOperationContextServerDomain String The default domain to use. Used only when SAP Mobile Platform Server is present. The domain separation should be supported by the SAP Mobile Platform Server. default
keyMAFLogonOperationContextFarmId String The default farm ID name if a Relay Server is included. EMPTY
keyMAFLogonOperationContextSecurityConfig String The default security configuration name. EMPTY
keyMAFLogonOperationContextGatewayClient String The default sap-client when communicating with the GW. EMPTY
keyMAFLogonOperationContextGatewayPingPath String The default GW ping path. sap/bc/ping
keyMAFLogonOperationContextResourcePath String The default path for routing through the reverse proxy if any exists. EMPTY
keyMAFLogonOperationContextBackendUserName String The default GW user name. EMPTY
keyMAFLogonOperationContextPasswordPolicy Dictionary The default password policy to apply if no server-side policy is provided. Default password policy
To set these values, use code similar to this:
//replace this with your way of accessing MAFLogonUIViewManager->NSObject<MAFLogonNGPublicAPI> (the logon manager public API)
NSMutableDictionary* defaultValues = [logonUIViewManager.logonManager defaultValues]; 

NSMutableDictionary* contextDefaultValues = [defaultValues objectForKey:@"keyMAFLogonOperationContextDefaultValues"];
NSMutableDictionary* registerContextType = [contextDefaultValues objectForKey:@"idMAFLogonOperationContextTypeRegister"];

[registerContextType setObject:@"300" forKey:@"keyMAFLogonOperationContextGatewayClient"];

[defaultValues setObject:contextDefaultValues forKey:@"keyMAFLogonOperationContextDefaultValues"];
These values are available for SAML registration.
Key Value Type Description Default Value
keyMAFLogonRegistrationContextConfig Dictionary    
keyMAFLogonRegistrationContextAuthConfigs Array .  
saml2.web.redirect.finish.endpoint.param String    
saml2.web.redirect.finish.endpoint String    
saml2.web.redirect.identifyingHeader.name String    
oauth2.authorizationEndpoint String    
oauth2.tokenEndpoint String    
oauth2.clientID String    
oauth2.scopes String    
keyMAFLogonRegistrationContextAuthType String Array    
When these values are set, SAML registration is executed. For example:
<key>keyMAFLogonRegistrationContextConfig</key>
		<dict>
			<key>keyMAFLogonRegistrationContextAuthConfigs</key>
			<array>
				<dict>
					<key>saml2.web.redirect.finish.endpoint.param</key>
					<string>finishEndpointParam</string>
					<key>saml2.web.redirect.finish.endpoint</key>
					<string>https://samlsdktesthmsdktenant.neo.ondemand.com/samlsdktest/SAMLAuthLauncher</string>
					<key>saml2.web.redirect.identifyingHeader.name</key>
					<string>com.sap.cloud.security.login</string>
				</dict>
			<!— example <dict>
					<key>oauth2.authorizationEndpoint</key>
					<string>https://samlsdktesthmsdktenant.neo.ondemand.com/samlsdktest/Authorization</string>
					<key>oauth2.tokenEndpoint</key>
					<string>https://samlsdktesthmsdktenant.neo.ondemand.com/samlsdktest/Token</string>
					<key>oauth2.clientID</key>
					<string>65465465465465465465465</string>
					<key>oauth2.scopes</key>
					<string>profile|feed</string>
				</dict> —->
			</array>
			<key>keyMAFLogonRegistrationContextAuthType</key>
			<array>
				<string>saml.web.post</string>
			<!— example <string> oauth2 </string> —->
			</array>
		</dict>

Enforcing Gateway-Only Registration

To enforce Gateway-only registration, use the keyMAFLogonOperationContextCommunicatorId field in the keyMAFLogonOperationContextHideRegistrationFields part of the MAFLogonOperationsDefaultValues.plist file. The default value is yes, which hides the field in the LogonUI.

To change the behavior, either set the value to no, or enter code, for example:
    // get current default values from LogonManager
    NSMutableDictionary* defaultValues = [logonUIViewManager.logonManager defaultValues];

     // get field visibility section
    NSMutableDictionary* contextDefaultValues = [defaultValues objectForKey:@"keyMAFLogonOperationContextHideRegistrationFields"];

    // set communicator id field visibility to NO (hide == NO)
    [contextDefaultValues setObject:[NSNumber numberWithBool:NO] forKey:@"keyMAFLogonOperationContextCommunicatorId"];

    // set back the default value to LogonManager
    [logonUIViewManager.logonManager setDefaultValues:defaultValues];

When you add the Gateway Only field to the LogonUI, it defaults to off; the server detection logic does not change. To enforce Gateway registration, turn it on. When it is on, LogonManager registers only to the Gateway server.

Integrating Directly with Logon Manager

MAFLogonManagerNG is an Objective-C library that you can integrate with any UI implementation. MAF includes a default native Logon UI, but you can also build your own UI.

This image shows a possible architecture of an application integrating directly with MAFLogonManagerNG without using MAFLogonUING:


Logon Architecture

You can integrate your own UI solution through the MAFLogonMediator by implementing your own LogonUIViewManager. This is similar to using the default MAFLogonUING implementation, because MAFLogonManagerNG uses context objects to construct the UI:
#import <UIKit/UIKit.h>

@protocol MAFLogonNGPublicAPI;
@protocol MAFLogonUICustomizationDelegate;

/**
 This class handles the navigation between the screens
 */
@interface MAFLogonUIViewManager : NSObject <MAFLogonUIViewManaging, MAFLogonUIViewManagingDelegate>

/**
 The logonMediator where the operations can be initiated. One has to set up the @see logonDelegate to be notified about the result of the operations
 */
@property (readonly) NSObject<MAFLogonNGPublicAPI> *logonMediator;

/**
 The actually presented viewController of the application. This will be used to present the logon related screens.
 */
@property (nonatomic, retain) UIViewController* parentViewController;
The LogonUIViewManager must store a reference to the LogonMediator and the presenting ViewController. The second property presents or dismisses a modal view. To initialize LogonUIViewManager, use:
- (id)init {
    self = [super init];
    if (self) {
        self.logonMediator = [[MAFLogonMediator alloc] init];
        self.logonMediator.logonUIViewManager = self;
    }
    return self;
}

To execute a logon operation, call:

- (IBAction)logonButtonTapped:(id)sender {
	[logonUIViewManager.logonManager logon];
}
MAFLogonManagerNG responds to the request through the MAFLogonUIViewManaging interface:
#pragma mark - MAFLogonUIViewManaging methods

-(void) showViewWithUIContext:(NSMutableDictionary *)aUIContext{
    if([[NSThread currentThread] isMainThread]){
        [self doShowViewWithUIContext:aUIContext];
    }
    else{
        dispatch_sync(dispatch_get_main_queue(), ^{
            [self doShowViewWithUIContext:aUIContext]; //do your custom UI building here!
        });
    }
}
- (void) operationRespondsWithOperationContext:(NSMutableDictionary *)anOperationContext error:(NSError *)anError {
    [currentViewManager operationRespondsWithOperationContext:anOperationContext error:anError];
}
-(void) closeUI {
    [currentViewManager release];
    currentViewManager = nil;
    currentOperationContextType = @"";
    
    [[self baseViewController] popToRootViewControllerAnimated:NO];
    [self.parentViewController dismissViewControllerAnimated:YES completion:^(void){
    }];
}

#pragma mark - MAFLogonUIViewManaging
- (void) operationRespondsWithOperationContext:(NSMutableDictionary *)anOperationContext error:(NSError *)anError {
    [self hideActivityIndicator];
    if (anError != nil && anError.code!=0) {
        [self presentError:anError];
    }
}

Supported Onboarding Scenarios

MAFLogonManagerNG supports multiple onboarding scenarios, based on the most common infrastructure setups supported by enterprise mobile applications. The customer's IT department can install SAP Mobile Platform and use relay server to route Internet requests to intranet-hosted Gateway systems. Another possibility is to use SAP Mobile Platform, but replace the relay server with IIS or Apache and use it as a reverse proxy.

Logon Method Selection

MAFLogonManagerNG determines the target infrastructure, which can be SAP Mobile Platform or Gateway. It uses this logic:


Logon Method Selection

The operation context object, which contains all information entered by the end user, passes the information to MAFLogonManagerNG. Based on the information, MAFLogonManagerNG decides whether the device user wants to use SAP Mobile Platform Server. If the user provides a farm ID , the logon manager constructs and sends an SAP Mobile Platform Server communicator-based test request.

Based on the test request response headers, code and cookies, the logon manager decides to use one of these scenarios:
  • Direct Gateway
  • Direct SAP Mobile Platform Server
  • SAP Mobile Platform Server with relay server
  • SAP Mobile Platform Server with third-party reverse proxy
If none of these scenarios are true, MAFLogonManagerNG cannot identify the communicator, and generates an error message.

Additionally, MAFLogonManagerNG searches for any information in the context and selects a method based on all of this information. The context can have default values that are configured by the application developer.

Success and Failure Handling

Onboarding consists of two steps. The first is registration, where MAFLogonManagerNG uses input from the device user to contact the server and register. If this step is successful, your application can send requests to the GW server and obtain data. The second step is to create a data vault on the user device, in which to securely store user credentials and other sensitive information. The data vault must be secured with a passcode and satisfy the requirements of the password policy.

Both of these steps can generate success and failure messages. Error messages are identified by an error code and an error domain, which fits into the iOS error message handling method. You can find definitions for error messages and error codes in the MAFLogonManagerNGErrors.h header file.
#define kErrorDomainLogonManager @"MAFLogonManagerNGErrorDomain"

#define errMAFLogonManagerErrorOperationCancelled           0
#define errMAFLogonManagerErrorInvalidParameter             1
#define errMAFLogonManagerErrorInvalidOperationCode         2
#define errMAFLogonManagerErrorCommunicationManagerError    3
#define errMAFLogonManagerErrorUserAlreadyLoggedIn          4
#define errMAFLogonManagerErrorOperationExecutionInProgress 5
#define errMAFLogonManagerErrorInvalidOperationContext      6
#define errMAFLogonManagerErrorInvalidCommunicatorId        7
#define errMAFLogonManagerErrorInvalidActionItemId          8
#define errMAFLogonManagerErrorCouldNotDecideCommunicator   9
#define errMAFLogonManagerErrorPasswordsNotEqual            10
#define errMAFLogonManagerErrorOperationNotAllowed          11
#define errMAFLogonManagerErrorInvalidServerHost            12
#define errMAFLogonManagerErrorInvalidBackendPassword       13
#define errMAFLogonManagerErrorPasscodeChangeNotEnabled     14
#define errMAFLogonManagerErrorUploadTraceFailed            15