This pages shows you how to setup Java Demo (Server Side SDK) App using discovery and without discovery.

Content:

  • Configuring and running Demo App in With Discovery Mode
  • Using Mobile Connect Server Side SDK With Discovery
  • Configuring and running Demo App in Without Discovery Mode
  • Using Mobile Connect Server Side SDK Without Discovery
  • Using common Mobile Connect Server Side SDK functionality
  • Configuring and running the server side SDK in With Discovery Mode

    1. Register an account or login to the Mobile Connect Developer Portal and create an application to obtain your sandbox credentials.
    2. Download the Mobile Connect server side project.

      git clone https://github.com/Mobile-Connect/java_server_side_library.git
    3. Note: if you operate in the EU then you should use EU Discovery Service domain in discovery url: https://eu.discover.mobileconnect.io.

    4. Open the configuration file: [local path]\mobile-connect-demo\src\main\resources\config\OperatorData.json.
      Here are 12 parameters:
      {
        "clientID": your client Id,
        "clientSecret": your client Secret,
        "clientName": your client Name,
        "discoveryURL": your Discovery endpoint,
        "redirectURL": "<protocol>://<hostname>/server_side_api/discovery_callback",
        "xRedirect": "True",
        "includeRequestIP": "False",
        "apiVersion": api version,
        "scope": scope,
        "acrValues":  acr_values,
        "MaxDiscoveryCacheSize": max cache size, 
        "loginHintTokenPreference": "True"
      }
    5. Open sector_identifier_uri.json file and specify the value of sector_identifier_uri with a single JSON array of redirect_uri values.
      ["<protocol>://<hostname>/server_side_api/discovery_callback"]
    6. Build the project. You can configure your application (clientID, clientSecret, discoveryURL, redirectURL). You can also configure your parameters for auth request (xRedirect, includeRequestIP, apiVersion, scope, acrValues). You can configure cache size (maxDiscoveryCacheSize) and if you want to run or not to run get user info request and get identity request (userInfo, identity). And you can set preference (loginHintTokenprefetence) to use login_hint_token parameter except login_hint.
    7. Build Demo App using Maven repository:
      cd java_server_side_library
      mvn clean package
    8. Deploy mobile-connect.war.
    9. Prepare client side application (IOS or Android application) or Demo App for Server Side application.

    Using Mobile Connect Server Side SDK with Discovery

    Client side application allows to sends a request to server side application in three modes: msisdn, mcc_mnc, none

    Example request:
    If you are using only msisdn the request to your server side part will be: http://localhost:8080/server_side_api/start_discovery?msisdn=447700900907
    When you are using mcc and mnc it will be: http://localhost:8080/server_side_api/start_discovery?mcc=907&mnc=07
    If you choose None mode: http://localhost:8080/server_side_api/start_discovery
    Also ip can be included to request: as query param sourceIp http://localhost:8080/server_side_api/start_discovery?sourceIp=10.0.0.7 or as value of X-Forwarded-For header.

    Client side application sends a GET request with client data to server side application. Then server side application makes startDiscovery method call with your data from configuration file. To interact with Discovery API is used attemptDiscovery method with your parameters from config file and client data. And then startAuthentication method perfoms for getting authentication URL. Server side application sends this URL to client side application.

    public RedirectView startDiscovery(
                @RequestParam(required = false) final String msisdn,
                @RequestParam(required = false) final String mcc,
                @RequestParam(required = false) final String mnc,
                @RequestParam(required = false) String sourceIp,
                @RequestParam(required = false) boolean ignoreIp,
                final HttpServletRequest request)
        {
            LOGGER.info("* Attempting discovery for msisdn={}, mcc={}, mnc={}, sourceIp={}",
                    LogUtils.mask(msisdn, LOGGER, Level.INFO), mcc, mnc, sourceIp);
            this.mobileConnectWebInterface = MobileConnect.buildWebInterface(mobileConnectConfig, new DefaultEncodeDecoder(), this.sessionCache, this.discoveryCache);
            this.getParameters();
    
            if (StringUtils.isNullOrEmpty(sourceIp) & !ignoreIp) {
                sourceIp = includeRequestIP ? HttpUtils.extractClientIp(request) : null;
            }
    
            DiscoveryResponse discoveryResponse = getDiscoveryCache(msisdn, mcc, mnc, sourceIp);
            MobileConnectStatus status;
    
            if (discoveryResponse == null) {
                status = attemptDiscovery(msisdn, mcc, mnc, sourceIp, request);
                discoveryResponse = status.getDiscoveryResponse();
    
                if (discoveryResponse == null  || discoveryResponse.getResponseCode() !=
                        org.apache.http.HttpStatus.SC_OK) {
                    if (status.getUrl() != null) {
                        return new RedirectView(status.getUrl(), true);
                    }
                    else {
                        return startDiscovery(null, null, null, null, true, request);
                    }
                }
            }
    
            setDiscoveryCache(msisdn, mcc, mnc, sourceIp, discoveryResponse);
    
            String url;
            if (operatorParams.getScope().contains(Scope.AUTHZ)) {
                url = startAuthorize(
                        discoveryResponse,
                        discoveryResponse.getResponseData().getSubscriberId(),
                        request,
                        msisdn, mcc, mnc, sourceIp);
            } else {
                url = startAuthentication(
                        discoveryResponse,
                        discoveryResponse.getResponseData().getSubscriberId(),
                        request,
                        msisdn, mcc, mnc, sourceIp);
            }
    
            if (url == null) {
                return startDiscovery(null, null, null, null, true, request);
            }
    
            return new RedirectView(url);
        }

    To generate the request parameters it uses getParameters method:

    private void getParameters() {
            operatorParams = ReadAndParseFiles.readFile(Constants.CONFIG_FILE_PATH);
            if(operatorParams == null) {
                operatorParams = ReadAndParseFiles.readFile(Constants.CONFIG_FILE_PATH.replace("file:/", ""));
            }
            if(operatorParams == null) {
                operatorParams = ReadAndParseFiles.readFile(Constants.CONFIG_FILE_PATH.replace("file:", ""));
            }
    
            apiVersion = operatorParams.getApiVersion();
            includeRequestIP = operatorParams.getIncludeRequestIP().equals("True");
            loginHintTokenPreference = operatorParams.getLoginHintTokenPreference().equals("True");
            if (!apiVersion.equals(DefaultOptions.MC_V3_0)) {
                loginHintTokenPreference = false;
            }
            sessionCache = new SessionCache.Builder()
                    .withJsonService(this.jsonService)
                    .withMaxCacheSize(operatorParams.getMaxDiscoveryCacheSize())
                    .build();
            clientName = operatorParams.getClientName();
    
            discoveryCache = new DiscoveryCache.Builder().withJsonService(this.jsonService).withMaxCacheSize(operatorParams.getMaxDiscoveryCacheSize()).build();
            try {
                mobileConnectConfig = new MobileConnectConfig.Builder()
                        .withClientId(operatorParams.getClientID())
                        .withClientSecret(operatorParams.getClientSecret())
                        .withClientName(operatorParams.getClientName())
                        .withDiscoveryUrl(new URI(operatorParams.getDiscoveryURL()))
                        .withRedirectUrl(new URI(operatorParams.getRedirectURL()))
                        .withXRedirect(operatorParams.getXRedirect().equals("True") ? "APP" : "False")
                        .withIncludeRequestIP(includeRequestIP)
                        .build();
            } catch (URISyntaxException e) {
                LOGGER.error("Wrong URI provided");
            }
        }

    1) If you selected the msisdn mode: stateDiscoveryCallback method is called.

    public ModelAndView stateDiscoveryCallback(@RequestParam(required = false) String state,
                                                   @RequestParam(required = false) final String error,
                                                   @RequestParam(required = false) final String error_description,
                                                   @RequestParam(required = false) final String description,
                                                   final HttpServletRequest request)
        {
            String operationStatus;
            if (error != null)
            {
                if (operatorParams.getScope().contains(Scope.AUTHN) || operatorParams.getScope().equals(Scope.OPENID)) {
                    operationStatus = Status.AUTHENTICATION;
                } else {
                    operationStatus = Status.AUTHORISATION;
                }
                return redirectToView(MobileConnectStatus.error(error,
                        ObjectUtils.defaultIfNull(description, error_description), new Exception()), operationStatus);
            }
    
            final MobileConnectRequestOptions options = new MobileConnectRequestOptions.Builder()
                    .withAuthenticationOptions(new AuthenticationOptions.Builder()
                            .withContext((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.CONTEXT_BINDING_MSG : null)
                            .withBindingMessage((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.CONTEXT_BINDING_MSG : null)
                            .withClientName(clientName)
                            .build())
                    .build();
    
            URI requestUri = HttpUtils.extractCompleteUrl(request);
            SessionData sessionData = sessionCache.get(state);
            MobileConnectStatus status = this.mobileConnectWebInterface.handleUrlRedirect(request, requestUri,
                    sessionData.getDiscoveryResponse(), state, sessionData.getNonce(), options, apiVersion, true);
    
            if (apiVersion.equals(DefaultOptions.VERSION_MOBILECONNECT) && !StringUtils.isNullOrEmpty(sessionData.getDiscoveryResponse().getOperatorUrls().getUserInfoUrl())) {
                for (String userInfoScope : userinfoScopes) {
                    if (operatorParams.getScope().contains(userInfoScope)) {
                        final MobileConnectStatus statusUserInfo =
                                this.mobileConnectWebInterface.requestUserInfo(request, sessionData.getDiscoveryResponse(),
                                        status.getRequestTokenResponse().getResponseData().getAccessToken());
                        status = status.withIdentityResponse(statusUserInfo.getIdentityResponse());
                        break;
                    }
                }
    
            } else if ((apiVersion.equals(DefaultOptions.MC_V3_0) || apiVersion.equals(DefaultOptions.MC_V2_3) || apiVersion.equals(DefaultOptions.MC_V2_0))
                    && !StringUtils.isNullOrEmpty(sessionData.getDiscoveryResponse().getOperatorUrls().getPremiumInfoUri())) {
                for (String identityScope : identityScopes) {
                    if (operatorParams.getScope().contains(identityScope)) {
                        final MobileConnectStatus statusIdentity =
                                this.mobileConnectWebInterface.requestIdentity(request, sessionData.getDiscoveryResponse(),
                                        status.getRequestTokenResponse().getResponseData().getAccessToken());
                        status = status.withIdentityResponse(statusIdentity.getIdentityResponse());
                        break;
                    }
                }
            } else {
                return redirectToView(status, Status.TOKEN);
            }
    
            return redirectToView(status, Status.PREMIUMINFO);
        }
        }

    This method calles handleUrlRedirect (where a token will receive) and also requestUserInfo or requestIdentity if it was specified in the configuration.

    2) mcc_mnc mode.
    3) none mode.

    If you selected the mcc_mnc mode or none mode you will be redirected to the operator selection page. Here you can type your msisdn and process page.
    Then mccMncDiscoverycallback method is called to enter phone number.

        final MobileConnectRequestOptions options = new MobileConnectRequestOptions.Builder()
                    .withAuthenticationOptions(new AuthenticationOptions.Builder()
                            .withContext((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.CONTEXT_BINDING_MSG : null)
                            .withBindingMessage((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.CONTEXT_BINDING_MSG : null)
                            .withClientName(clientName)
                            .build())
                    .build();
    
            String[] mccMncArray = mcc_mnc.split("_");
            String mcc = mccMncArray[0];
            String mnc = mccMncArray[1];
    
            MobileConnectStatus status = this.mobileConnectWebInterface.attemptDiscovery(request, null, mcc, mnc, true, mobileConnectConfig.getIncludeRequestIp(), options);
    
            if (status.getDiscoveryResponse() != null) {
                setDiscoveryCache(null, mcc, mnc, null, status.getDiscoveryResponse());
                String url;
                if (operatorParams.getScope().contains(Scope.AUTHZ)) {
                    url = startAuthorize(
                            status.getDiscoveryResponse(),
                            subscriber_id,
                            request, null, mcc, mnc, null);
                } else {
                    url = startAuthentication(
                            status.getDiscoveryResponse(),
                            subscriber_id,
                            request, null, mcc, mnc, null);
                }
                return new RedirectView(url);
            }
            else {
                return new RedirectView(status.getUrl(), true);
            }

    Discovery caching

    Demo Server Side SDK records each successful Discovery Response in Discovery Cache.
    Adding, getting and removing records is performing by using a key that includes user MSISDN, MCC, MNC, IP.
    Record is removing from cache only in case of expired Discovery Response. Response expiration is determined by “ttl” (time to live) parameter value processing in Discovery Response.
    The ‘ttl’ value should be in the following range:

  • more than 5mins;
  • less than 259200mins.
  • In case of ‘ttl’ value is less than 5mins, Discovery Response’s ‘ttl’ is overwritten with 5mins.
    In case of ‘ttl’ value is more than 259200mins, Discovery Response’s ‘ttl’ is overwritten with 259200mins.
    There no cache autoremove mechanism or clearing cache based on the Authentication/Authorisation error response. Removing from cache can occur only during an attempt to get a record. Discovery Cache receives request for a record with particular key. Inner mechanism search record in storage and performs verification. If Response is expired, record will be removed and Cache won’t return expired response.

    Using Mobile Connect Authentication/Authorisation

    The server side SDK allows you to call the Identity Gateway with the scope parameter set to “mc_authz”, which signifies an authorisation request for a single transaction (the id_token and access token returned from the Gateway have a timeout set to zero, so expire after a single use).

    To make a successful authorisation call, you must provide the following additional parameters:

    • client_name – specifies the name of the application/service requesting authorisation.
    • context – specifies the reason for the authorisation request, and should be built from the data describing the transaction requiring authorisation. The context is displayed on the authenticating (mobile) device only.
    • binding_message– specifies a reference string to display on the device from which the authorisation request was invoked, and on the authenticating (mobile) device, allowing the user to visually verify that the confirmation message originated from their transaction request.

    Note: the authorisation prompt displayed to the user combines all three parameters, which cannot exceed 93 bytes in total.

    The following example shows how to add the additional options to the authentication call described in Using Mobile Connect Authentication, resulting in a correctly configured call to the authorisation service.

    public String startAuth(
                @RequestParam(required = false) final DiscoveryResponse discoveryResponse,
                @RequestParam(required = false) final String subscriberId, final HttpServletRequest request, final String msisdn,
                final String mcc, final String mnc, final String sourceIp)
    {
        …
    
        final MobileConnectRequestOptions options = new MobileConnectRequestOptions.Builder()
                    .withAuthenticationOptions(new AuthenticationOptions.Builder()
                            .withScope(scope)
                            .withContext((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.CONTEXT_BINDING_MSG : null)
                            .withBindingMessage((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.BINDING_MSG : null)
                            .withClientName(clientName)
                            .withLoginHintToken(subscriberIdToken)
                            .build())
                    .build();
    
        …
    }

    The startAuth method generates URL for authorisation, which is sent to client side application.

    public String startAuth(
                @RequestParam(required = false) final DiscoveryResponse discoveryResponse,
                @RequestParam(required = false) String subscriberId, final HttpServletRequest request, final String msisdn,
                final String mcc, final String mnc, final String sourceIp)
        {
            String scope = operatorParams.getScope();
            String subscriberIdToken = discoveryResponse.getResponseData().getSubscriberIdToken();
            try {
                if (!VersionDetection.getCurrentVersion(apiVersion, scope, discoveryResponse.getProviderMetadata()).equals(DefaultOptions.MC_V3_0)) {
                    loginHintTokenPreference = false;
                }
            } catch (InvalidScopeException e) {
                e.printStackTrace();
            }
            if (!loginHintTokenPreference && !StringUtils.isNullOrEmpty(subscriberId)) {
                subscriberIdToken = null;
            } else if (!StringUtils.isNullOrEmpty(subscriberIdToken)) {
              subscriberId = null;
            }
    
            final MobileConnectRequestOptions options = new MobileConnectRequestOptions.Builder()
                    .withAuthenticationOptions(new AuthenticationOptions.Builder()
                            .withScope(scope)
                            .withContext((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.CONTEXT_BINDING_MSG : null)
                            .withBindingMessage((apiVersion.equals(Constants.VERSION_2_0) || apiVersion.equals(Constants.VERSION_2_3) || apiVersion.equals(Constants.VERSION_3_0)) ? Constants.BINDING_MSG : null)
                            .withClientName(clientName)
                            .withLoginHintToken(subscriberIdToken)
                            .build())
                    .build();
            final MobileConnectStatus status =
                    this.mobileConnectWebInterface.startAuthentication(request, discoveryResponse, subscriberId,
                            null, null, options, apiVersion);
    
            if (status.getErrorMessage() != null) {
                return null;
            }
            setSessionCache(status, msisdn, mcc, mnc, sourceIp);
    
            return status.getUrl();
        }

    Also, please, see

  • Using common Mobile Connect Server Side SDK functionality
  • Configuring and running the server side SDK in Without Discovery Mode

    1. Register an account or login to the Mobile Connect Developer Portal and create an application to obtain your sandbox credentials.
    2. Download the Mobile Connect server side project.

      git clone https://github.com/Mobile-Connect/java_server_side_library.git
    3. Note: if you operate in the EU then you should use EU Discovery Service domain in discovery url: https://eu.discover.mobileconnect.io.

    4. Open the configuration file: [local path]\mobile-connect-demo\src\main\resources\config\WithoutDiscoveryData.json to pass required parameter values for without discovery mode.
      Here are 17 parameters:
      {
        "clientID": your client Id,
        "clientSecret": your client Secret,
        "clientName": your client Name,
        "discoveryURL": your Discovery endpoint,
        "redirectURL": "<protocol>://<hostname>/server_side_api/discovery_callback",
        "xRedirect": "True",
        "includeRequestIP": "True",
        "apiVersion": api version: "mc_v1.1", "mc_v2.0" or "mc_di_r2_v2.3",
        "scope": scope,
        "acrValues": acr_values,
        "MaxDiscoveryCacheSize": max cache size,
        "operatorUrls": {
          "authorizationUrl": authorize endpoint,
          "requestTokenUrl": token endpoint,
          "userInfoUrl": userinfo endpoint,
          "premiumInfoUri": premiuminfo endpoint,
          "providerMetadataUri": provider metadata endpoint
        }
      }
    5. Open sector_identifier_uri.json file and specify the value of sector_identifier_uri with a single JSON array of redirect_uri values.
      ["<protocol>://<hostname>/server_side_api/discovery_callback"]
    6. Build the project. You can configure your application (clientID, clientSecret, discoveryURL, redirectURL). You can also configure your parameters for auth request (xRedirect, includeRequestIP, apiVersion, scope, acrValues). And You can configure cache size (maxDiscoveryCacheSize) and if you want to run or not to run get user info request and get identity request (userInfo, identity).
    7. Download and install any missing dependencies.
    8. Build Demo App using Maven repository:
      cd java_server_side_library
      mvn clean package
    9. Deploy mobile-connect.war.
    10. Prepare client side application (IOS or Android application) or Demo App for Server Side application.

    Using Mobile Connect without Discovery

    The server side SDK allows you to call methods that get additional parameters from a JSON configuration file. Once the end user has entered MSISDN and intitiated session from the client side, the server side SDK builds the call to the Authorize endpoint. A successful authentication returns an id_token containing the user’s PCR, which is unpacked and available for verification against your user register.

    This SDK allows calls to Mobile Connect without first doing a Discovery call. It is a similar process to usual Mobile Connect Authentication but instead of calls to the Discovery Service a new function makeDiscoveryForAuthorization is used to create the discoveryOptions object.

    Using Mobile Connect Authentication/Authorisation

    Client side application sends a GET request with MSISDN to server side application.
    Example request:

    http://localhost:8080/server_side_api/start_discovery_manually?msisdn=your_msisdn

    Then server side application makes startAuthenticationWithoutDiscovery method call for getting authentication URL.

       public RedirectView startAuthenticationWithoutDiscovery(
                @RequestParam(required = false) final String msisdn,
                final HttpServletRequest request)
        {
    
            LOGGER.info("* Attempting discovery for msisdn={}", LogUtils.mask(msisdn, LOGGER, Level.INFO));
    
            DiscoveryResponse discoveryResponse = null;
            try {
                discoveryResponse = this.mobileConnectWebInterface.generateDiscoveryManually(clientSecret, clientId,
                        clientName, operatorUrls);
            } catch (JsonDeserializationException e) {
                LOGGER.warn("Can't create discoveryResponse");
            }
    
            String url;
    
            if (operatorParams.getScope().contains(Scope.AUTHZ)) {
                url = startAuthorize(
                        discoveryResponse,
                        msisdn,
                        request);
            } else {
                url = startAuthentication(
                        discoveryResponse,
                        msisdn,
                        request);
            }
    
            return new RedirectView(url);
        }

    Using Mobile Connect Identity and Attributes

    A successful call to the Authorisation endpoint returns an id_token identifying the user, and an access token that grants your application permission to request their personal information (referred to as Claims). This information contains a range of data; the exact data you can request is specified in the access token, and is limited to those Claims the end user has permitted as part of the original authorisation request.

    Note: the access token is for single use only, and expires immediately upon use.

    You request access to the Identity endpoint by specifying the appropriate scope. The server side SDK provides constants that you can pass when requesting specific Identity products:

    • Identity: Phone Number – MC_PHONE
    • Identity: Sign-up – MC_SIGNUP
    • Identity: National Identity – MC_NATIONALID

    Upon successful authorisation, the server side SDK provides an IdentityResponse with the user information JSON available as a property. The following example can be used to convert the JSON data to a class - IdentityData - which is provided with all recognised claims.

    final MobileConnectStatus response =
                this.mobileConnectWebInterface.requestIdentity(request, discoveryResponse, accessToken);
    
    final IdentityResponse identityResponse = response.getIdentityResponse();

    The following example shows how to add the additional Authorisation and Identity options to the Authentication call described in Using Mobile Connect Authentication, resulting in a correctly configured call to the Identity: Phone Number service.

    Note: calls to Identity: Sign-up and Identity: National ID are structured in exactly the same way, but using the scopes “mc_signup” (“mc_identity_signup”) and “mc_nationalid” (“mc_identity_nationalid”) as applicable.

    Add the MobileConnectRequestOptions required for Authorisation and Identity: Phone Number.

    Add the requestIdentity() and requestUserInfo() method calls to request the identity data following a successful authorisation.

    public ModelAndView StateDiscoveryCallback(@RequestParam(required = false) String state,
                                              @RequestParam(required = false) final String error,
                                              @RequestParam(required = false) final String error_description,
                                              @RequestParam(required = false) final String description,
                                              final HttpServletRequest request)
        {
            ...
    
            if (apiVersion.equals(DefaultOptions.VERSION_MOBILECONNECT) && !StringUtils.isNullOrEmpty(sessionData.getDiscoveryResponse().getOperatorUrls().getUserInfoUrl())) {
                for (String userInfoScope : userinfoScopes) {
                    if (operatorParams.getScope().contains(userInfoScope)) {
                        final MobileConnectStatus statusUserInfo =
                                this.mobileConnectWebInterface.requestUserInfo(request, sessionData.getDiscoveryResponse(),
                                        status.getRequestTokenResponse().getResponseData().getAccessToken());
                        status = status.withIdentityResponse(statusUserInfo.getIdentityResponse());
                        break;
                    }
                }
    
            } else if ((apiVersion.equals(DefaultOptions.MC_V3_0) || apiVersion.equals(DefaultOptions.MC_V2_3) || apiVersion.equals(DefaultOptions.MC_V2_0))
                    && !StringUtils.isNullOrEmpty(sessionData.getDiscoveryResponse().getOperatorUrls().getPremiumInfoUri())) {
                for (String identityScope : identityScopes) {
                    if (operatorParams.getScope().contains(identityScope)) {
                        final MobileConnectStatus statusIdentity =
                                this.mobileConnectWebInterface.requestIdentity(request, sessionData.getDiscoveryResponse(),
                                        status.getRequestTokenResponse().getResponseData().getAccessToken());
                        status = status.withIdentityResponse(statusIdentity.getIdentityResponse());
                        break;
                    }
                }
            } else {
                return redirectToView(status, Status.TOKEN);
            }
    
               ...
        }