Index: oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java =================================================================== --- oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java (Revision 1861506) +++ oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/AbstractLoginModule.java (Arbeitskopie) @@ -46,8 +46,10 @@ import org.apache.jackrabbit.oak.spi.security.authentication.callback.RepositoryCallback; import org.apache.jackrabbit.oak.spi.security.authentication.callback.UserManagerCallback; import org.apache.jackrabbit.oak.spi.security.authentication.callback.WhiteboardCallback; +import org.apache.jackrabbit.oak.spi.security.principal.AdminPrincipal; import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration; import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider; +import org.apache.jackrabbit.oak.spi.security.principal.SystemPrincipal; import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration; import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard; import org.jetbrains.annotations.NotNull; @@ -57,6 +59,8 @@ import org.osgi.annotation.versioning.ProviderType; +import static org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants.PARAM_ADMINISTRATIVE_PRINCIPALS; + /** * Abstract implementation of the {@link LoginModule} interface that can act * as base class for login modules that aim to authenticate subjects against @@ -188,7 +192,7 @@ @Override public boolean logout() { boolean success = false; - if (!subject.getPrincipals().isEmpty() && !subject.getPublicCredentials(Credentials.class).isEmpty()) { + if (!subject.getPrincipals().isEmpty() && (!subject.getPublicCredentials(Credentials.class).isEmpty() || isAdminOrSystem(subject.getPrincipals()) )) { // clear subject if not readonly if (!subject.isReadOnly()) { subject.getPrincipals().clear(); @@ -199,6 +203,20 @@ return success; } + private boolean isAdminOrSystem(@NotNull Set principals) { + if (principals.contains(SystemPrincipal.INSTANCE)) { + return true; + } else { + Set adminNames = options.getConfigValue(PARAM_ADMINISTRATIVE_PRINCIPALS, Collections.EMPTY_SET); + for (Principal principal : principals) { + if (principal instanceof AdminPrincipal || adminNames.contains(principal.getName())) { + return true; + } + } + return false; + } + } + @Override public boolean abort() throws LoginException { clearState();