How to not allow login portal

I have a system with a portal and several APIs for other systems. And multiple users of my system.

Some user should have data access privilege to data of my system, but I do not want them to login to my portal.

Actually, I have only one user(admin) can login to my portal, all other users not allow portal(only allowed from api).

Is there a way to configure this rather than control in code level?

Hi!

You can easily implement this with a custom UserAccessChecker bean. It enables you to customize access rules on the middleware.

Create PortalLoginAccessChecker class in the core module and annotate it with @Component annotation:

package com.company.portallogin.core.security;

import com.haulmont.cuba.core.global.ClientType;
import com.haulmont.cuba.core.global.Messages;
import com.haulmont.cuba.security.auth.AuthenticationDetails;
import com.haulmont.cuba.security.auth.Credentials;
import com.haulmont.cuba.security.auth.LoginPasswordCredentials;
import com.haulmont.cuba.security.auth.checks.AbstractUserAccessChecker;
import com.haulmont.cuba.security.global.LoginException;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.Locale;

@Component
public class PortalLoginAccessChecker extends AbstractUserAccessChecker {
    @Inject
    private Logger log;

    public PortalLoginAccessChecker(Messages messages) {
        super(messages);
    }

    @Override
    public void check(Credentials credentials, AuthenticationDetails authenticationDetails) throws LoginException {
        if (credentials instanceof LoginPasswordCredentials) {
            LoginPasswordCredentials loginPassword = (LoginPasswordCredentials) credentials;

            if (loginPassword.getClientType() == ClientType.PORTAL
                    && !"admin".equals(loginPassword.getLogin())) {

                Locale userLocale;
                if (loginPassword.getLocale() != null) {
                    userLocale = loginPassword.getLocale();
                } else {
                    userLocale = messages.getTools().getDefaultLocale();
                }

                log.warn("Attempt to login from portal {}", loginPassword.getLogin());

                throw new LoginException(getInvalidCredentialsMessage(loginPassword.getUserIdentifier(), userLocale));
            }
        }
    }
}

Here we check if login is performed from PORTAL client and if login is not “admin” LoginException is thrown.

Custom access checkers should implement UserAccessChecker interface or subclass AbstractUserAccessChecker class.

Built-in “cuba.gui.loginToClient” permission is implemented the same way, see ClientTypeUserAccessChecker class.

1 Like

Thanks, I will try this way. And BTW don’t I need to invoke super.check(…) after my own check logic?

It is not required, since AbstractUserAccessChecker does not have check implementation.

Hi,
The solution works, but it can’t customize the error message show in web, I noticed that in below code of IDPController, it always raise “invalid credential” message.
image

All localization messages are defined in client JS, not on server side. Server side only returns error code.

I mean since server return “invalid credentail” , but in fact , error is not “invalid credential”, in fact, it is system does allow user login to portal.

Hi Yuriy,
Any other solution for this topic? The way using UserAccessChecker does not work. Because the server is also a SSO IDP server, the check added as you suggested also prevents user login other SPs.

So any other suggestions?

You could use custom Credentials instance and check only this type of credentials in your checker.