iampass

The IAMPASS Flutter plugin is used to connect applications to the IAMPASS system.

For an overview of the system see the Getting Started Guide. Pay particular attention to sections for custom iOS and and Android apps as this contains information about configuring your application permissions and entitlements.

The package can be used to:

  • Create an application that uses IAMPASS for authentication.
  • Create an application that receives IAMPASS authentication requests, collects authentication data and send it to IAMPASS. Your application can support both but MUST support the push notification method if your users can login from different applications, such as a web application. The package supports iOS and Android.

All of the functionaility is provided by the class Iampass.

import 'package:iampass/iampass.dart';
...
class _MyAppState extends State<MyApp> {
  final _iampassPlugin = Iampass();
  ...
  }

Getting Started

Create an IAMPASS Account

Before your application can use IAMPASS you must create an IAMPASS account and application. See the Getting Started Guide.

Configuring you iOS Application

The IAMPASS plugin uses custom values stored in the info.plist file for your iOS app.

<key>IAMPASS-AppID</key>
<string> Your IAMPASS application ID</string>
<key>IAMPASS-AppSecret</key>
<string>Your IAMPASS application secret</string>

See the custom iOS guide.

Configuring an Android Application

See the custom Android guide for instructions about configuring your Android application.

Users

IAMPASS requires that you register your users. You should not use the users' usernames but instead generate an identifier for the user that is passed to IAMPASS. Users can be registered in your mobile application or a separate application. If users are registered in a separate application they must register a mobile device before they can authenticate

Registering Users

Users can be registered in your mobile app or in an external application such as a web application.

Using iampass.addUser

To register users in your mobile application you can use iampass.addUser. This will register an IAMPASS user, register the current mobile device and perform an training required. In the example below userID is the identifier the application use for the user and notificationToken is a notification token obtained from the platform push notification system (APNS, FCM). If your application does not use push notifications for authentication you can use any string starting with the * character for notificationToken. The created user is stored in shared preferences so that it can be retrieved when the application restarts. In addition the user is stored in the _currentUser member of the state so that it can be used in subseqent calls.

    try {
      

      await _iampassPlugin.addUser(userID, notificationToken).then((user) {
        if (user != null) {
          // The user has been added.
          // Save the user data to shared preferences so that it can
          // be retrieved when the app is restarted.
          String encoded = jsonEncode(user);
          encryptedSharedPreferences.setString("user", encoded);

          setState(() {
            _currentUser = user;
            _appUserID = userID;
          });
        }
      });
    } on PlatformException catch (e) {
      // The plugin failed to complete the request.
      // The code and message properties of the exception provide information
      // about the cause of failure.
      ...
    } catch (e) {
        // A generic exception occurred.
        ...
    }

Register a Device for an existing user

If you have already registered a user with IAMPASS but have not registered their mobile device you can use iampass.registerUser. In the example below userID is the identifier the application use for the user and notificationToken is a notification token obtained from the platform push notification system (APNS, FCM). If your application does not use push notifications for authentication you can use any string starting with the * character for notificationToken. The created user is stored in shared preferences so that it can be retrieved when the application restarts. In addition the user is stored in the _currentUser member of the state so that it can be used in subseqent calls.

    try {

      await _iampassPlugin
          .registerDevice(userID, notificationToken)
          .then((device) {
        if (device != null) {
          // Save the user data.
          String encoded = jsonEncode(device);
          encryptedSharedPreferences.setString("user", encoded);
          setState(() {
            _currentUser = device;
          });
        }
      });
    } on PlatformException catch (e) {
      // The plugin failed to complete the request.
      // The code and message properties of the exception provide information
      // about the cause of failure.
      ...
    } catch (e) {
      // A generic exception occurred.
      ...
    }
  }

Updating Users

When you application starts up or the applications push notification token changes you should call iampass.updateUser with your stored IAMPASSUser. The return value of this method is an updated version your user and should replace then stored value. The example below

  • Calls updateUser
  • If training is required the training flow is initiated.
  • If training is not required the updated user is saved.
  void onUpdateUser() async {
    try {
      await _iampassPlugin
          .updateUser(_appUserID, _currentUser!, "*notificationToken")
          .then((user) {
        // The user has been updated.
        if (user != null) {
          showSuccessMessage("updateUser Succeeded");
          if (user.trainingRequired) {
            // Do training
            doTraining(user);
          } else {
            String encoded = jsonEncode(user);
            encryptedSharedPreferences.setString("user", encoded);
            setState(() {
              _currentUser = user;
            });
            ...
          }
        }
      });
    } on PlatformException catch (e) {
      ...
    } catch (e) {
      ...
    }
  }

  void doTraining(IAMPASSUser user) async {
    try {
      await _iampassPlugin.trainUser(_currentUser!).then((user) {
        // The user has been updated.
        if (user != null) {
            String encoded = jsonEncode(user);
            encryptedSharedPreferences.setString("user", encoded);
            setState(() {
              _currentUser = user;
            });
          ...
        }
      });
    } on PlatformException catch (e) {
      ...
    } catch (e) {
      ...
    }
  }

Deleting Users

To delete a user call iampass.deleteUser.

    bool deleted = await _iampassPlugin.deleteUser(userID);

    if (deleted) {
      ...
    } else {
      ...
    }
    // Remove the stored user data.
    encryptedSharedPreferences.remove("user");
    setState(() {
      _currentUser = null;
    });

Authentication

In app Authentication

If your application is directly authenticating users you can use iampass.authenticateUser. This method will display the authentication UI and return an IAMPASSAuthenticationSession that can be used to control the user's authentication state. This method can only be used for authentication events triggered in your mobile app. No push notifications are used. In the example below userID is the id of the user and currentUser is an IAMPASSUser obtained by registering this mobile device.

void onAuthenticateUser() async {
    try {
      // Create the authentication parameters.
      // In this case we are going to use the default duration and authentication
      // methods.
      IAMPASSStartAuthenticationParams params =
          IAMPASSStartAuthenticationParams(
              userID, null, null, currentUser!);

      await _iampassPlugin.authenticateUser(params).then((session) {
        if (session == null) {
          // Authentication failed.
        } else {
          // Authentication completed.
          // Use session.isAuthenticated to check the result
          ...
        }
      });
    } on PlatformException catch (e) {
      // Authentication Failed.
    } catch (e) {
      // Authentication Failed.
    }
  }

Your application should save the returned IAMPASSAuthenticationSession and use it to check the user's authentication status before allowing access to protected resources. The sessions's status is cached. Applications should call iampass.updateSession to update the cached value.

Acting as an Authenticator App

If your application is intended to act as an IAMPASS authenticator app for users in an external app such as a web app, you will need to add push notification handling to your application. You will also have to obtain a valid notification token before calling user registration methods. IAMPASS uses FCM for Android push notifications and APNS or FCM for iOS. When your application receives a push notification it should:

  • Check if the notification is from IAMPASS
  • Construct an IAMPASSAuthenticationRequest from the notification payload.
  • Call iampass.handleAuthenticationRequest.
func application(
      _ application: UIApplication,
      didReceiveRemoteNotification userInfo: [AnyHashable: Any],
      fetchCompletionHandler completionHandler:
      @escaping (UIBackgroundFetchResult) -> Void
    ) {
        // Check that the user info has the action key
        if let action = data["action"] as? String{
        
            // Is this an identification request?
            if action == "identify"{
                // This is an IAMPASS authentication request
            }
      }

For FCM messages the payload is

    "data" : {
        "action": "identify",
        ... IAMPASS data.
    }

if action == "identify the message payload can be converted to json and converted to an IAMPASSAuthenticationRequest using IAMPASSAuthenticationRequest.fromJson. Your application should check that the push notification is for a user registered on this device by comparing the userID property of the request to the userID property of the stored IAMPASSUser. If the values match the application should pass the request and user to handleAuthenticationRequest.

Checking the status of a session

Your application should use IAMPASSAuthenticationSession to check whether a user is authenticated. The status of the session is cached so you should call iampass.updateSession to refresh the status, then check session.isAuthenticated.

try {
      await _iampassPlugin
          .updateSession(currentSession!)
          .then((updatedSession) {
        if (updatedSession != null) {
          
          setState(() {
            _currentSession = updatedSession;
          });

          // session has been updated
          // check whether user is still authenticated
         if( updatedSession.isAuthenticated){
            // User is authenticated
         }
        }
      });
    }  on PlatformException catch (e) {
      // Update  Failed.
    } catch (e) {
      // Update Failed.
    }

Ending a Session

To end a session (log out a user) use `iampass.endSession'.

try {
      await _iampassPlugin.endSession(_currentSession!).then((ended) {
        if (ended) {
          // Session ended
          setState(() {
            _currentSession = null;
          });
        }
      });
    }   on PlatformException catch (e) {
      // end session failed.
    } catch (e) {
      // end session failed.
    }