Permitted IP Address Functionality With Version 7.2.6

Hi Team,

Kindly your support regarding below issue

on our production environment we are using version 7.2.4 and Permitted IP Address Functionality is working fine their , And on pre-prod we are using 7.2.6 but Permitted IP Address is not working.

We have custom Login Controller and nothing changed from both version from our side.

below is our doLogin Function.

Even when i tried to downgrade the version to 7.2.4 and buld UberJar
I got Error Error: An unexpected error occurred while trying to open file vpay.jar

@Override
public void doLogin() {
    String login = loginField.getValue();
    String password = passwordField.getValue() != null ? passwordField.getValue() : "";

    if (StringUtils.isEmpty(login) || StringUtils.isEmpty(password)) {

        notifications.create()
                .withDescription(messages.getMainMessage("loginWindow.emptyLoginOrPassword"))
                .withType(Notifications.NotificationType.WARNING)
                .withPosition(Notifications.Position.BOTTOM_RIGHT)
                .show();
        return;
    }

    try {

        VPayUser user;
        Credentials credentials;

        credentials = new LoginPasswordCredentials(login, password, app.getLocale());
        user = (VPayUser) authenticationService.authenticate(credentials).getSession().getUser();

        user = userService.reloadLoginUser(user.getId());
        boolean isAdmin = user.getUserRoles().stream().anyMatch(userRole -> userRole.getRole().getType() == RoleType.SUPER);
        boolean isESS = user.getEmployee() != null;
        boolean isAppAdmin = user.getCanBeAssignedToCountry() || !user.getAssignableOrganizations().isEmpty();

        boolean continueLogon = true;

        if (isAdmin) {
            changeUserGroup(user, Constants.ROOT_GROUP_USERS);
            continueLogon = true;
        } else if (isESS) {
            if (!isAppAdmin) {
                changeUserGroup(user, Constants.ESS_GROUP_USERS);
                continueLogon = true;
            } else {
                if (this.isESS.isVisible()) {
                    if (this.isESS.isChecked()) {
                        changeUserGroup(user, Constants.ESS_GROUP_USERS);
                    } else {
                        changeUserGroup(user, Constants.VIRTUA_GROUP_USERS);
                    }
                    continueLogon = true;
                } else {
                    this.isESS.setVisible(true);
                    continueLogon = false;
                    String roleTypeMsg = messageBundle.getMessage("vpay.login.type");
                    notifications.create()
                            .withDescription(roleTypeMsg)
                            .withPosition(Notifications.Position.BOTTOM_RIGHT)
                            .withType(Notifications.NotificationType.HUMANIZED).show();
                }
            }
        } else {
            changeUserGroup(user, Constants.VIRTUA_GROUP_USERS);
            continueLogon = true;
        }

        if (continueLogon && !user.getCanBeAssignedToCountry() && user.getUserRoles().stream().anyMatch(userRole -> userRole.getRole().getType() == RoleType.SUPER) == false) {
            if (user.getAssignableOrganizations().size() == 1) {
                if (licenseService.isApplicationUsageExpired(user.getAssignableOrganizations().get(0).getOrganization())) {
                    continueLogon = false;
                    showLicenseExpiredMsg();
                }
            } else if (user.getAssignableOrganizations().size() == 0 && isESS) {
                if (licenseService.isApplicationUsageExpired(user.getEmployee().getEmployeesGroup().getOrganization())) {
                    continueLogon = false;
                    showLicenseExpiredMsg();
                }
            }
        }

        if (continueLogon) {
            credentials = new LoginPasswordCredentials(login, password, app.getLocale());
            doLogin(credentials);

            // locale could be set on the server
            if (connection.getSession() != null) {
                Locale loggedInLocale = connection.getSession().getLocale();

                if (globalConfig.getLocaleSelectVisible()) {
                    app.addCookie(App.COOKIE_LOCALE, loggedInLocale.toLanguageTag());
                }
            }
        }
    } catch (InternalAuthenticationException e) {
        log.error("Internal error during login", e);

        showUnhandledExceptionOnLogin(e);
    } catch (LoginException e) {
        log.info("Login failed: {}", e.toString());

        String message = StringUtils.abbreviate(e.getMessage(), 1000);
        showLoginException(message);
    } catch (Exception e) {
        log.warn("Unable to login", e);

        showUnhandledExceptionOnLogin(e);
    }
}

Hi,
Most probably in your pre-prod environment you get incorrect client IP addresses due to a proxy or something. Check what is shown in the Address field in the User Sessions browser.

Hi Konstantin ,

Thanks for your replay ,Let me elaborate the full issue to you and seeking your guidance.

we have our pre-prod environment structure as below

Amazon Load balance behind we have 2 Ec2 Instances With shared EFS directories

If we are accessing application using our domain which redirect to load balance the ip address that is appearing on user-sessions-browser is same for all users

If we hit one of the nodes directly it is showing the correct ip address for the logged in user

What do you think the issue for that?

Thanks

Hi @knstvk ,

Can you please give me any hint for the issue , or just guide me for the root cause of the issue

Perhaps you need help from someone with good knowledge of AWS.

1 Like

Hi,

Behind the LB you do not by default get the IP address of the client. However, as most load balancer products, the x-forwarded-for HTTP header is used for providing this information to the server.

AWS LB also adds the HTTP header HTTP headers and Classic Load Balancers - Elastic Load Balancing to the requests when forwarding it to the server.

Cheers
Mario

Hi Mario ,

Thanks for your replay , AWS LB is changing the ip address for the client in case of forwarding , and on our system we are using the origin ip address for the user to permit only users to access application from only specific ip in case of forwarding , the ip address that application is fetching is one of the Ec2 instance behind LB which is causing that non of the users is able to access of the application from the permitted ip address

we changed the LB from forward to redirect and that one is causing changing url in the browser to the node which is not the right way to handle

I’m just wondering if their is any way on AWS LB to add to original ip address of the user while forwarding the request .

Thanks

Yes, as I said:

When forwarding, the load balancer adds the header to the HTTP request. This can be used by the server to look it up. Probably you have to fiddle around with some nginx config in oder to get that header in the app.

Here’s a discussion that explains you how to do it: How to obtain external IP Address of users? - #3 от пользователя albudarov - CUBA.Platform

Cheers
Mario

Hi Mario ,
Thanks for your explanation,

The thing is that I’m depending on the Cuba Platform permitted ip address which is provided while user creation , and in user sessions screen under administration module same explained on the link you shared.

I did already configured jetty.xml with the configuration even with ssl and every thing is working perfect if only connecting to one of the nodes directly , this issue is only happening while connecting from LB

Below is jetty.xml used currently and working perfect in case only of one node but not the case with LB

<Configure id="Server" class="org.eclipse.jetty.server.Server">
    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server">
                    <Ref refid="Server"/>
                </Arg>
                <Set name="port">8080</Set>
            </New>
        </Arg>
    </Call>

    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server">
                    <Ref refid="Server"/>
                </Arg>
                <Arg>
                    <New class="org.eclipse.jetty.util.ssl.SslContextFactory">
                        <Set name="keyStorePath">/usr/src/vp/keystore.jks</Set>
                        <Set name="keyStorePassword">password</Set>
                        <Set name="keyManagerPassword">password</Set>
                        <Set name="trustStorePath">/usr/src/vp/keystore.jks</Set>
                        <Set name="trustStorePassword">password</Set>
                    </New>
                </Arg>
                <Set name="port">443</Set>
            </New>
        </Arg>
    </Call>
</Configure>

If you can suggest any modification for that

Thanks :slight_smile:

What do you mean in the concrete? Have you tried what @AlexBudarov shared in the other topic? What did not work?

Cheers
Mario

Cuba platform is providing feature to permit user to access application from only specific ip address user users screen image

And for the topic , I’m actually doing exactly what he explained their , if you checked my shared jetty.xml it is exactly the same but we are using keystore on the application level for SSL purpose .

Hi @@AlexBudarov ,

Can you please assist on that case , As @mario refered to your post which actually we are following to get the results but still We are not able to get the actual ip address for the logged in user

below is my current jetty.xml if you can please assist on that

<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
        <Set name="outputBufferSize">32768</Set>
        <Set name="requestHeaderSize">8192</Set>
        <Set name="responseHeaderSize">8192</Set>
        <Call name="addCustomizer">
            <Arg>
                <New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/>
            </Arg>
        </Call>
    </New>

    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server">
                    <Ref refid="Server"/>
                </Arg>
                <Arg name="factories">
                    <Array type="org.eclipse.jetty.server.ConnectionFactory">
                        <Item>
                            <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                                <Arg name="config">
                                    <Ref refid="httpConfig"/>
                                </Arg>
                            </New>
                        </Item>
                    </Array>
                </Arg>
                <Set name="port">8080</Set>
            </New>
        </Arg>
    </Call>

    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server">
                    <Ref refid="Server"/>
                </Arg>
                <Arg>
                    <New class="org.eclipse.jetty.util.ssl.SslContextFactory">
                        <Set name="keyStorePath">/usr/src/vp/keystore.jks</Set>
                        <Set name="keyStorePassword">Uhg80DjQb0</Set>
                        <Set name="keyManagerPassword">Uhg80DjQb0</Set>
                        <Set name="trustStorePath">/usr/src/vp/keystore.jks</Set>
                        <Set name="trustStorePassword">Uhg80DjQb0</Set>
                    </New>
                </Arg>
                <Set name="port">443</Set>
            </New>
        </Arg>
    </Call>
</Configure>

Hi,
As I see, you are using SSL decryption right in the CUBA application server.
If so, then what is your configuration of the Amazon ELB Load Balancer?

Normally one should set up Amazon ELB to decrypt SSL traffic, specifying necessary certificate data there (add an HTTPS listener to the Load Balancer object with SSL certificate assigned).

Note that if cloud load balancer does not decrypt SSL, it will not be able to change http request headers (to add X-Forwarded-To header with original IP address of the request). And without X-Forwarded-To header you will not know original IP address of the request.

1 Like

Hi @AlexBudarov ,

Thanks for your response , I will check with Devops team and update you.

Thanks alot

Hi , We solved the issue

First we removed the keystore section from the jetty.xml

ALB has SSL certificate installed with X-Forward-For

Ec2 Instances are defined under private target group so no access to them from outside

our application is deployed on http port but not 8080

ALB is working over 443 port

Thanks all for your support

1 Like