Portal login API - IP restrictions

Hi There,

I wondered if it would be possible to make the portal login API respect any IP restrictions that have been put in place for a particular user account. The CUBA web frontend itself obviously does this by default, and I would like to extend this to the portal.

An additional question that I have is whether there are any DB entries / logs created when the portal login API is used? I would like to be able to present to users the date/time their account was last used and the IP from which it was used.

I could do this by creating a separate web service to record and recall this information, but it seems better that the information is recorded by the login API for security/provability reasons.

Many thanks!

1 Like

Hi,

for now, it is not implemented in the portal module, but you can add such a functionality yourself in your project.

You need to add your custom implementation of Connection interface and define it in portal-spring.xml file.

  1. IpMaskSecuredConnection

package com.company.demo.portal.sys;

import com.haulmont.cuba.portal.sys.PortalConnection;

public class IpMaskSecuredConnection extends PortalConnection {

}
  1. Define it in portal-spring.xml

...
<bean name="cuba_Connection" class="com.company.demo.portal.sys.IpMaskSecuredConnection" scope="prototype"/>
...
  1. Add IP mask checking logic:

public class IpMaskSecuredConnection extends PortalConnection {
    @Inject
    private Messages messages;

    private ThreadLocal<String> ipAddressHolder = new ThreadLocal<>();

    @Override
    public synchronized void login(String login, String password, Locale locale, @Nullable String ipAddress,
                                   @Nullable String clientInfo) throws LoginException {
        ipAddressHolder.set(ipAddress);
        try {
            super.login(login, password, locale, ipAddress, clientInfo);
        } finally {
            ipAddressHolder.remove();
        }
    }

    @Override
    protected UserSession doLogin(String login, String password, Locale locale) throws LoginException {
        String ipAddress = ipAddressHolder.get();

        UserSession session = super.doLogin(login, password, locale);

        if (!StringUtils.isBlank(session.getUser().getIpMask())) {
            IpMatcher ipMatcher = new IpMatcher(session.getUser().getIpMask());
            if (!ipMatcher.match(ipAddress)) {
                log.info(String.format("IP address %s is not permitted for user %s", ipAddress,
                        session.getUser().toString()));

                // logout session on middle ware
                SecurityContext currentSecurityContext = AppContext.getSecurityContext();
                try {
                    AppContext.setSecurityContext(new SecurityContext(session));
                    loginService.logout();
                } finally {
                    AppContext.setSecurityContext(currentSecurityContext);
                }

                throw new LoginException(messages.getMainMessage("login.invalidIP"));
            }
        }

        return session;
    }
}

It is a very tricky approach, but it enables you to perform such an additional checking. I’ve added the sample project so you can try it in action.

Thank you for your feedback,
we will add IP mask checking to the portal in one of the next releases.

portal-ip-mask.zip (36.9K)

1 Like

Thanks very much for coming back to me with such a detailed response - much appreciated.