User registration
Before you add user registration to your application, the Android SDK must already be added to your application.
The Android SDK uses the OAuth 2.0 protocol to authorize the device to access protected resources. To support this protocol, the Android SDK acts as an OAuth 2.0 client.
Prerequisites
For registration to work, OneginiBrowserRegistrationRequestHandler
and OneginiCustomAuthenticationRequestHandler
must be set in OneGiniClientBuilder
.
To initialize authentication, client credentials are required. Client credentials are generated using Dynamic Client Registration (DCR). DCR is included by default in the Android SDK. For DCR, it is mandatory that the time on the device is equal to the time on the Mobile Identity module.
DCR errors are reported back to the Android SDK via the event handler. DCR requires that the application authenticates itself to the IDAAS-core by sending the identifier, version, and platform of the application.
Initializing registration
The UserClient
offers the registerUser
method. The registerUser()
method should be used when a user wants to register. Calling the UserClient#registerUser()
for an already registered user results in a reregistration. The registerUser
method requires the following three arguments:
OneginiIdentityProvider
is the identity provider to use for registration.String[]
lists the scopes that authentication is requested for. When no scopes are requested, the default scopes of the application are used.OneginiRegistrationHandler
is the registration handler to return the authentication result to.
User registration starts with enrolling a user on a device using a selected identity provider (IdP). A primary (default) IdP and the list of available IdPs for an app are configured in the IDAAS-core.
After enrollment with the selected IdP, the Android SDK receives a refresh token and initializes a PIN creation request to get the user's PIN. The PIN is used to store the refresh token encrypted on the device. Depending on the setting chosen by the app developer, the user can confirm the entered PIN. To specify the PIN creation request handler, the app developer sets it on the OneginiClientBuilder
.
After successful PIN creation, the Android SDK calls the onSuccess(UserProfile userProfile, final CustomInfo customInfo)
method from the OneginiRegistrationHandler
.
In the event of user registration failure, the Android SDK calls the onError(OneginiRegistrationError error)
method. You can handle errors that are relevant to you differently. To accomplish this, compare the OneginiRegistrationError#getErrorType()
value with the OneginiRegistrationError
error type definitions. The OneginiRegistrationError
also contains an additional error description for debugging and possibly a Throwable
object that you can get with the getMessage()
and getCause()
methods.
Example: registration of a new user profile with a default IdP
Initializing registration with a selected IdP
To register a user using a different IdP than the one set as default on the IDAAS-core, you can provide a OneginiIdentityProvider
instance as a parameter. The (Set<OneginiIdentityProvider>)
list of available IdPs can be checked by calling the UserClient#getIdentityProviders()
method.
Example code: fetching a set of possible IdPs
The platform supports two main types of IdPs: browser and custom API. Both types of IdPs can be defined and configured in the IDAAS-core. All IdPs that are configured by the app are returned by the Android SDK as a OneginiIdentityProvider
interface.
Example code: registration of a new user profile
Registering with a browser-based IdP
To support registering with a browser-based IdP, the Android SDK must request an access grant from the IDAAS-core using the browser. The Android SDK can accomplish this using the OneginiBrowserRegistrationRequestHandler
.
The handler should be then passed to the Android SDK with the OneginiClientBuilder#setBrowserRegistrationRequestHandler
method.
In the event that browser registration is requested, the Android SDK notifies the application using OneginiBrowserRegistrationRequestHandler#startRegistration()
. The application should then use the provided URL to ask for the access grant in a web browser.
If the client credentials are correct and the user gets their access granted, the IDAAS-core redirects the user back to the app. Because the app is a layer on top of the Android SDK, the Android SDK cannot handle this redirect itself. It is the responsibility of the app to handle the redirect and delegate it to the Android SDK. When delegating a redirect, the Android SDK verifies whether the redirect has the right syntax and whether it should be handled by the Android SDK.
The app can handle a redirect by specifying a scheme in the AndroidManifest.xml
of the application. Ensure that you set the same scheme in both the OneginiConfigModel
and the MIDAAS-core configuration.
If the client credentials are invalid, the IDAAS-core is not able to redirect the user back to the app. The Android SDK validates the client credentials and refreshes them before redirecting to the IDAAS-core to receive an access grant.
If user authentication in web browser failed or was canceled, you can abort the registration action by calling OneginiBrowserRegistrationCallback#denyRegistration()
.
Example code - AndroidManifest.xml
On success, the Android SDK begins using the received authorization grant. Based on this authorization grant, an access token is requested for the specified set of scopes. When the client has the refresh token grant type, a refresh token is returned with the created access token.
Example code: to handle a registration callback
Registration with a custom IdP
To support registering with an IdP that has a custom API, the Android SDK must use the custom registration functionality delivered by the application using OneginiCustomIdentityProvider
and OneginiCustomRegistrationAction
. To use a custom IdP, it must be enabled and configured on the IDAAS-core side and implemented in the application.
One-step registration
The Android SDK asks the app for optional registration data. The data is sent to the IDAAS-core, where the custom registration script is executed. The result of the custom script (status code and optional data) is sent back to the Android SDK and the registration result is propagated to the application.
Two-step registration
The Android SDK asks the app for optional initial registration data. The data is sent to the IDAAS-core, where the custom registration is initialized. The optional initialization result is sent back to the Android SDK. Then the Android SDK asks the app for a registration data, providing the optional initialization data provided by the IDAAS-core. The registration data is sent to the IDAAS-core, where the custom registration script is executed. The result of the custom script (status code and optional data) is sent back to the Android SDK and the registration result is propagated to the application.
OneginiCustomIdentityProvider
To use a custom IdP, you must provide an implementation of the OneginiCustomIdentityProvider
interface to the Android SDK. The implementation provides the unique ID of the IdP along with methods that should be called during registration.
Example code: for OneginiCustomIdentityProvider implementation
OneginiCustomRegistrationAction
The OneginiCustomRegistrationAction
interface is used to request a registration from the app and deliver the registration result back to the Android SDK.
If using one-step registration, the OneginiCustomIdentityProvider
should provide an implementation of OneginiCustomRegistrationAction
, which includes the finishRegistration
method:
Example code: for OneginiCustomRegistrationAction implementation
If using two-step registration, the OneginiCustomIdentityProvider
should provide an implementation of OneginiCustomTwoStepRegistrationAction
, which extends the OneginiCustomRegistrationAction
to provide an additional initRegistration
method:
The OneginiCustomRegistrationCallback
is a handler that allows you to provide either the optional data that should be sent to the backend (extension engine script) or an exception that occurred during the registration. In case of an exception, the Android SDK ends the registration with a GENERAL_ERROR
and original exception included as a cause.
The CustomInfo
object contains a status code and optional data provided by the backend script. The first step of the registration flow always returns null CustomInfo
. This means that the object is null in the finishRegistration
method of the one-step registration flow and in the initRegistration
method of the two-step registration.
The only exception to this rule is a retry of the registration step. In case of a recoverable error returned by the Android SDK, the CustomInfo
object in the retried step contains the error info.
There are three groups of status codes that can be returned in the CustomInfo
object:
success status (2XXX)
: When the status code is in the 2000 - 2999 range, the registration step has been finished successfully.recoverable errors (4XXX)
: When the status code is in the 4000 - 4999 range, the flow can be recovered and the Android SDK calls either theOneginiCustomTwoStepRegistrationAction#initRegistration
or theOneginiCustomTwoStepRegistrationAction#finishRegistration
method again, depending on the step that caused the error.unrecoverable errors (5XXX)
: When the status code is in the 5000 - 5999 range, the flow cannot be recovered and the Android SDK returns an error instead of retrying the step.
Example code: for custom registration action implementation
Initializing the OneginiClient
To provide implementations of the OneginiCustomIdentityProvider
to the Android SDK, you can use OneginiClientBuilder#addCustomIdentityProvider
or OneginiClientBuilder#setCustomIdentityProviders
to either add one implementation to the Android SDK or give a set of supported custom IdPs.
Example code: initialize the Android SDK with custom IDP
Registering stateless user
Stateless registration does not create a user profile. You can implement stateless registration using registerStatelessUser
. The access token created in the process has the Stateless
type. This makes it possible to implement support for App2App authentication towards external identity schemas that do not support derived identities (like DigiD) in a custom registration script.
Stateless registration flow works exactly the same as the other custom registrations, with the exception that at the end of the registration flow:
PIN
creation handler is not triggered, which means no PIN for the user session.User Profile
is not stored, which results in limited Android SDK capabilities because part of the functions require theUser Profile
parameter.Refresh Token
is stored as part of the session. WhenAccess Token
is expired, theRefresh Token
is automatically used to prolong the session. This can also be done manually using stateless session refresh.
To use stateless authentication, it must be enabled in your application and you must be using a custom IdP.
With stateless authentication enabled, you can registerStatelessUser
from the UserClient
interface.
Registration with a third-party mobile application
Registration with third-party mobile applications is possible using two-step custom registration.
A number of properties need to be set up on the backend side, so be sure that it is properly configured. A two-step custom registration IDP with scripts for both init
and complete
steps need to be set up. The third-party app needs to be installed on the device, and ready to receive and emit app links.
Flow overview
- The app initiates custom registration with an
init
request. - There is an
Init
response with thesessionId
andapp link
. - The app opens the third-party app using the
app link
. - The third-party app authenticates the user and navigates back to the app using the
app link.
- The app extracts the
artefactId
from theapp link
and sends it to the backend along with thesessionId
. - Registration finishes and the app receives an access or a refresh token.
- Proceed with the PIN creation flow.
Example of the flow
Your app needs to be able to receive app links from the third-party app. Be sure to register the correct app link
in your manifest file.
Implement OneginiCustomTwoStepRegistrationAction interface.
On successful authentication in third-party app, it runs app link
back into your app with a json
response. Unpack the response value, parse it with sessionId
into new a json
, and send it back do the backend via callback.onSuccess(json)
from the finishRegistration
method.
Implement OneginiCustomIdentityProvider interface
In the example above, the IDP ID is app2app
. Be sure to use an IDP ID that is set in your backend.