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?
artamonov
(Yuriy Artamonov)
April 19, 2018, 4:56pm
#3
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
anjingjing
(Jingjing An)
April 20, 2018, 5:53am
#5
Thanks, I will try this way. And BTW don’t I need to invoke super.check(…) after my own check logic?
artamonov
(Yuriy Artamonov)
April 20, 2018, 11:05am
#6
It is not required, since AbstractUserAccessChecker
does not have check
implementation.
anjingjing
(Jingjing An)
February 20, 2019, 7:53am
#7
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.
artamonov
(Yuriy Artamonov)
February 20, 2019, 7:54am
#8
All localization messages are defined in client JS, not on server side. Server side only returns error code.
anjingjing
(Jingjing An)
February 20, 2019, 8:11am
#9
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.
anjingjing
(Jingjing An)
February 21, 2019, 6:15am
#10
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?
artamonov
(Yuriy Artamonov)
February 21, 2019, 7:00am
#11
You could use custom Credentials
instance and check only this type of credentials in your checker.