Obtaining the user’s geodata#

The login procedure can be used to obtain data about the country and city where the user is located, and based on this, flexibly configure the login rules, for example, to prohibit login from abroad, activate the second authentication factor, etc.

To do this, use the following classes and methods in the login procedures:

  1. LGeoData class with getCountry() and getCity() functions.

    public class LGeoData {
        /**
        *  Get IP address country
        *
        * @return - country or null if country not specified.
        */
        public final String getCountry();
    
        /**
        *  Get IP address city
        *
        * @return - city or null if city not specified.
        */
    
        public final String getCity();
    }
    
  2. geoData() method in Context.

    /**
     * Get geo data of user IP address
     *
     * @return - geo data.
     */
     LGeoData geoData();
    

    Important

    For the method to work, you need to import the LGeoData class.

    import com.identityblitz.idp.login.authn.flow.LGeoData
    
An example of the code that outputs the user’s country and city to the log#
import com.identityblitz.idp.login.authn.flow.LGeoData;

LGeoData geoData = _ctx.geoData();
String country = geoData.getCountry();
logger.trace("IP location: country - {}, city - {}, factor - {}", country , geoData.getCity());
An example of a procedure involving 2FA for certain countries#
package com.identityblitz.idp.flow.dynamic;

import java.lang.*;
import java.util.*;
import java.text.*;
import java.time.*;
import java.math.*;
import java.security.*;
import javax.crypto.*;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import com.identityblitz.idp.login.authn.flow.api.*;
import com.identityblitz.idp.login.authn.flow.Context;
import com.identityblitz.idp.login.authn.flow.Strategy;
import com.identityblitz.idp.login.authn.flow.StrategyState;
import com.identityblitz.idp.login.authn.flow.StrategyBeginState;
import com.identityblitz.idp.login.authn.flow.LCookie;
import com.identityblitz.idp.login.authn.flow.LUserAgent;
import com.identityblitz.idp.login.authn.flow.LBrowser;
import com.identityblitz.idp.login.authn.flow.LGeoData;
import com.identityblitz.idp.federation.matching.JsObj;
import com.identityblitz.idp.flow.common.api.*;
import com.identityblitz.idp.flow.dynamic.*;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.lang.invoke.LambdaMetafactory;
import java.util.function.Consumer;
import static com.identityblitz.idp.login.authn.flow.StrategyState.*;

public class EnableSecondFactorByCountry implements Strategy {

    private final Logger logger = LoggerFactory.getLogger("com.identityblitz.idp.flow.dynamic");

    @Override public StrategyBeginState begin(final Context ctx) {
        if ("login".equals(ctx.prompt())){
            List<String> methods = new ArrayList<String>(Arrays.asList(ctx.availableMethods()));
            methods.remove("cls");
            return StrategyState.MORE(methods.toArray(new String[0]), true);
        } else {
            if(ctx.claims("subjectId") != null)
                return StrategyState.ENOUGH();
            else
                return StrategyState.MORE(new String[]{});
        }
    }

    @Override public StrategyState next(final Context ctx) {
        Integer reqFactor = (ctx.user() == null) ? null : ctx.user().requiredFactor();
        LGeoData geoData = ctx.geoData();
        String country = geoData.getCountry();
        logger.info("IP location: country - {}, city - {}, factor - {}", country , geoData.getCity());
        if(ctx.justCompletedFactor() == 1 && (country == null || !country.equals("Russia")))
            return StrategyState.MORE(new String[]{});
        else
            return StrategyState.ENOUGH();
    }
}