You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2019/08/02 08:46:23 UTC
[isis] branch v2 updated: ISIS-2157 fixes auto-create user related
vulnerability
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/v2 by this push:
new a4e3acd ISIS-2157 fixes auto-create user related vulnerability
a4e3acd is described below
commit a4e3acdaea7262b5a54579f646197c41348924fd
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Aug 2 10:46:14 2019 +0200
ISIS-2157 fixes auto-create user related vulnerability
When using delegated authentication, desired behavior is to auto-create
user accounts in the DB only if these do successfully authenticate with
the delegated authentication mechanism, while the newly created user
will be disabled by default.
---
.../secman/shiro/IsisModuleSecurityRealm.java | 82 ++++++++++++++--------
1 file changed, 51 insertions(+), 31 deletions(-)
diff --git a/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java b/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java
index c7179b6..e18344a 100644
--- a/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java
+++ b/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java
@@ -24,11 +24,11 @@ import java.util.function.Supplier;
import javax.inject.Inject;
+import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.extensions.secman.api.SecurityRealm;
import org.apache.isis.extensions.secman.api.SecurityRealmCharacteristic;
import org.apache.isis.extensions.secman.api.encryption.PasswordEncryptionService;
import org.apache.isis.extensions.secman.api.user.AccountType;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser;
import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
import org.apache.isis.runtime.system.context.IsisContext;
import org.apache.isis.runtime.system.persistence.PersistenceSession;
@@ -77,32 +77,36 @@ public class IsisModuleSecurityRealm extends AuthorizingRealm implements Securit
val password = usernamePasswordToken.getPassword();
// lookup from database, for roles/perms
- val principal = lookupPrincipal(username);
+ val principal = lookupPrincipal_inApplicationUserRepository(username);
+
+ val autoCreateUserWhenDelegatedAuthentication = hasDelegateAuthenticationRealm() && getAutoCreateUser();
+ if (principal == null && autoCreateUserWhenDelegatedAuthentication) {
+ // When using delegated authentication, desired behavior is to auto-create user accounts in the
+ // DB only if these do successfully authenticate with the delegated authentication mechanism,
+ // while the newly created user will be disabled by default
+ authenticateElseThrow_usingDelegatedMechanism(token);
+ val newPrincipal = createPrincipal_inApplicationUserRepository(username);
+
+ _Assert.assertNotNull(newPrincipal);
+ _Assert.assertTrue("Auto-created user accounts must be initially disabled!", newPrincipal.isDisabled());
+
+ throw disabledAccountException(username); // default behavior after user auto-creation
+ }
+
if (principal == null) {
// if no delegate authentication
throw new CredentialsException("Unknown user/password combination");
}
if (principal.isDisabled()) {
- // this is the default if delegated account and automatically created
- throw new DisabledAccountException(String.format("username='%s'", principal.getUsername()));
+ throw disabledAccountException(principal.getUsername());
}
if(principal.getAccountType() == AccountType.DELEGATED) {
- AuthenticationInfo delegateAccount = null;
- if (hasDelegateAuthenticationRealm()) {
- try {
- delegateAccount = delegateAuthenticationRealm.getAuthenticationInfo(token);
- } catch (AuthenticationException ex) {
- // fall through
- }
- }
- if(delegateAccount == null) {
- throw new CredentialsException("Unknown user/password combination");
- }
+ authenticateElseThrow_usingDelegatedMechanism(token);
} else {
- final CheckPasswordResult result = checkPassword(password, principal.getEncryptedPassword());
- switch (result) {
+ val checkPasswordResult = checkPassword(password, principal.getEncryptedPassword());
+ switch (checkPasswordResult) {
case OK:
break;
case BAD_PASSWORD:
@@ -128,30 +132,46 @@ public class IsisModuleSecurityRealm extends AuthorizingRealm implements Securit
return urp;
}
- private PrincipalForApplicationUser lookupPrincipal(final String username) {
-
- //FIXME[2157] do not auto-create if user cannot authenticate
- // determine how to authenticate (delegate or local), whether disabled
- val autoCreateUser = hasDelegateAuthenticationRealm() && getAutoCreateUser();
+ private DisabledAccountException disabledAccountException(String username) {
+ return new DisabledAccountException(String.format("username='%s'", username));
+ }
+
+ private void authenticateElseThrow_usingDelegatedMechanism(AuthenticationToken token) {
+ AuthenticationInfo delegateAccount = null;
+ try {
+ delegateAccount = delegateAuthenticationRealm.getAuthenticationInfo(token);
+ } catch (AuthenticationException ex) {
+ // fall through
+ }
+ if(delegateAccount == null) {
+ throw new CredentialsException("Unknown user/password combination");
+ }
+ }
+
+ private PrincipalForApplicationUser lookupPrincipal_inApplicationUserRepository(final String username) {
return execute(new Supplier<PrincipalForApplicationUser>() {
@Override
public PrincipalForApplicationUser get() {
- val applicationUser = lookupUser();
+ val applicationUser = applicationUserRepository.findByUsername(username);
return PrincipalForApplicationUser.from(applicationUser);
}
-
- private ApplicationUser lookupUser() {
- if (autoCreateUser) {
- return applicationUserRepository.findOrCreateUserByUsername(username);
- } else {
- return applicationUserRepository.findByUsername(username);
- }
+ @Inject private ApplicationUserRepository applicationUserRepository;
+ });
+ }
+
+ private PrincipalForApplicationUser createPrincipal_inApplicationUserRepository(final String username) {
+
+ return execute(new Supplier<PrincipalForApplicationUser>() {
+ @Override
+ public PrincipalForApplicationUser get() {
+ val applicationUser = applicationUserRepository.findOrCreateUserByUsername(username);
+ return PrincipalForApplicationUser.from(applicationUser);
}
-
@Inject private ApplicationUserRepository applicationUserRepository;
});
}
+
private static enum CheckPasswordResult {
OK,