Skip to content

Commit

Permalink
Made auth plugins log to security log
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Oct 21, 2016
1 parent 8273ee7 commit 2ccb074
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 16 deletions.
Expand Up @@ -142,7 +142,7 @@ public EnterpriseAuthAndUserManager newAuthManager( Config config, LogProvider l
}

// Load plugin realms if we have any
realms.addAll( createPluginRealms( config, logProvider, secureHasher ) );
realms.addAll( createPluginRealms( config, securityLog, secureHasher ) );

// Select the active realms in the order they are configured
List<Realm> orderedActiveRealms = selectOrderedActiveRealms( configuredRealms, realms );
Expand Down Expand Up @@ -196,7 +196,7 @@ private static CacheManager createCacheManager( Config config )
return new ShiroCaffeineCache.Manager( Ticker.systemTicker(), ttl, maxCapacity );
}

private static List<Realm> createPluginRealms( Config config, LogProvider logProvider, SecureHasher secureHasher )
private static List<Realm> createPluginRealms( Config config, SecurityLog securityLog, SecureHasher secureHasher )
{
List<Realm> realms = new ArrayList<>();
Set<Class> excludedClasses = new HashSet<>();
Expand All @@ -212,7 +212,7 @@ private static List<Realm> createPluginRealms( Config config, LogProvider logPro
for ( AuthPlugin plugin : authPlugins )
{
PluginRealm pluginRealm =
new PluginRealm( plugin, config, logProvider, Clocks.systemClock(), secureHasher );
new PluginRealm( plugin, config, securityLog, Clocks.systemClock(), secureHasher );
realms.add( pluginRealm );
}
}
Expand All @@ -229,7 +229,7 @@ private static List<Realm> createPluginRealms( Config config, LogProvider logPro
if ( pluginAuthorizationEnabled && plugin instanceof AuthorizationPlugin )
{
// This plugin implements both interfaces, create a combined plugin
pluginRealm = new PluginRealm( plugin, (AuthorizationPlugin) plugin, config, logProvider,
pluginRealm = new PluginRealm( plugin, (AuthorizationPlugin) plugin, config, securityLog,
Clocks.systemClock(), secureHasher );

// We need to make sure we do not add a duplicate when the AuthorizationPlugin service gets loaded
Expand All @@ -239,7 +239,7 @@ private static List<Realm> createPluginRealms( Config config, LogProvider logPro
else
{
pluginRealm =
new PluginRealm( plugin, null, config, logProvider, Clocks.systemClock(), secureHasher );
new PluginRealm( plugin, null, config, securityLog, Clocks.systemClock(), secureHasher );
}
realms.add( pluginRealm );
}
Expand All @@ -255,7 +255,7 @@ private static List<Realm> createPluginRealms( Config config, LogProvider logPro
if ( !excludedClasses.contains( plugin.getClass() ) )
{
PluginRealm pluginRealm =
new PluginRealm( null, plugin, config, logProvider, Clocks.systemClock(), secureHasher );
new PluginRealm( null, plugin, config, securityLog, Clocks.systemClock(), secureHasher );
realms.add( pluginRealm );
}
}
Expand All @@ -267,8 +267,11 @@ private static List<Realm> createPluginRealms( Config config, LogProvider logPro
public static RoleRepository getRoleRepository( Config config, LogProvider logProvider,
FileSystemAbstraction fileSystem )
{
File authStoreDir = config.get( DatabaseManagementSystemSettings.auth_store_directory );
File roleStoreFile = new File( authStoreDir, ROLE_STORE_FILENAME );
return new FileRoleRepository( fileSystem, roleStoreFile, logProvider );
return new FileRoleRepository( fileSystem, getRoleRepositoryFile( config ), logProvider );
}

public static File getRoleRepositoryFile( Config config )
{
return new File( config.get( DatabaseManagementSystemSettings.auth_store_directory ), ROLE_STORE_FILENAME );
}
}
Expand Up @@ -40,7 +40,6 @@
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.internal.Version;
import org.neo4j.logging.Log;
import org.neo4j.logging.LogProvider;
import org.neo4j.server.security.enterprise.auth.PredefinedRolesBuilder;
import org.neo4j.server.security.enterprise.auth.SecureHasher;
import org.neo4j.server.security.enterprise.auth.ShiroAuthToken;
Expand All @@ -54,6 +53,7 @@
import org.neo4j.server.security.enterprise.auth.plugin.spi.AuthorizationPlugin;
import org.neo4j.server.security.enterprise.auth.plugin.spi.CustomCacheableAuthenticationInfo;
import org.neo4j.server.security.enterprise.auth.plugin.spi.RealmLifecycle;
import org.neo4j.server.security.enterprise.log.SecurityLog;

import static org.neo4j.server.security.enterprise.configuration.SecuritySettings.PLUGIN_REALM_NAME_PREFIX;

Expand All @@ -69,12 +69,12 @@ public class PluginRealm extends AuthorizingRealm implements RealmLifecycle, Shi

private RealmOperations realmOperations = new PluginRealmOperations();

public PluginRealm( Config config, LogProvider logProvider, Clock clock, SecureHasher secureHasher )
public PluginRealm( Config config, SecurityLog securityLog, Clock clock, SecureHasher secureHasher )
{
this.config = config;
this.clock = clock;
this.secureHasher = secureHasher;
this.log = logProvider.getLog( getClass() );
this.log = securityLog;

setCredentialsMatcher( new CredentialsMatcher() );

Expand All @@ -88,18 +88,18 @@ public PluginRealm( Config config, LogProvider logProvider, Clock clock, SecureH
}

public PluginRealm( AuthenticationPlugin authenticationPlugin, AuthorizationPlugin authorizationPlugin,
Config config, LogProvider logProvider, Clock clock, SecureHasher secureHasher )
Config config, SecurityLog securityLog, Clock clock, SecureHasher secureHasher )
{
this( config, logProvider, clock, secureHasher );
this( config, securityLog, clock, secureHasher );
this.authenticationPlugin = authenticationPlugin;
this.authorizationPlugin = authorizationPlugin;
resolvePluginName();
}

public PluginRealm( AuthPlugin authPlugin, Config config, LogProvider logProvider, Clock clock,
public PluginRealm( AuthPlugin authPlugin, Config config, SecurityLog securityLog, Clock clock,
SecureHasher secureHasher )
{
this( config, logProvider, clock, secureHasher );
this( config, securityLog, clock, secureHasher );
this.authPlugin = authPlugin;
resolvePluginName();
}
Expand Down
@@ -0,0 +1,154 @@
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.server.security.enterprise.auth.plugin;

import org.junit.Test;

import java.time.Clock;
import java.util.Collection;

import org.neo4j.kernel.configuration.Config;
import org.neo4j.logging.AssertableLogProvider;
import org.neo4j.server.security.enterprise.auth.SecureHasher;
import org.neo4j.server.security.enterprise.auth.plugin.api.AuthToken;
import org.neo4j.server.security.enterprise.auth.plugin.api.AuthenticationException;
import org.neo4j.server.security.enterprise.auth.plugin.api.RealmOperations;
import org.neo4j.server.security.enterprise.auth.plugin.spi.AuthInfo;
import org.neo4j.server.security.enterprise.auth.plugin.spi.AuthPlugin;
import org.neo4j.server.security.enterprise.auth.plugin.spi.AuthenticationInfo;
import org.neo4j.server.security.enterprise.auth.plugin.spi.AuthenticationPlugin;
import org.neo4j.server.security.enterprise.auth.plugin.spi.AuthorizationInfo;
import org.neo4j.server.security.enterprise.auth.plugin.spi.AuthorizationPlugin;
import org.neo4j.server.security.enterprise.auth.plugin.spi.RealmLifecycle;
import org.neo4j.server.security.enterprise.log.SecurityLog;

import static java.lang.String.format;
import static org.mockito.Mockito.mock;
import static org.neo4j.logging.AssertableLogProvider.inLog;

public class PluginRealmTest
{
private static final RealmOperations IGNORED = null;

private Config config = mock( Config.class );
private AssertableLogProvider log = new AssertableLogProvider();
private SecurityLog securityLog = new SecurityLog( log.getLog( this.getClass() ) );

@Test
public void shouldLogToSecurityLogFromAuthPlugin() throws Throwable
{
PluginRealm pluginRealm = new PluginRealm( new LoggingAuthPlugin(), config, securityLog, Clock.systemUTC(),
mock( SecureHasher.class ) );
pluginRealm.initialize( IGNORED );
assertLogged( "LoggingAuthPlugin" );
}

@Test
public void shouldLogToSecurityLogFromAuthenticationPlugin() throws Throwable
{
PluginRealm pluginRealm = new PluginRealm(
new LoggingAuthenticationPlugin(),
null,
config, securityLog, Clock.systemUTC(), mock( SecureHasher.class ) );
pluginRealm.initialize( IGNORED );
assertLogged( "LoggingAuthenticationPlugin" );
}

@Test
public void shouldLogToSecurityLogFromAuthorizationPlugin() throws Throwable
{
PluginRealm pluginRealm = new PluginRealm(
null,
new LoggingAuthorizationPlugin(),
config, securityLog, Clock.systemUTC(), mock( SecureHasher.class ) );
pluginRealm.initialize( IGNORED );
assertLogged( "LoggingAuthorizationPlugin" );
}

private void assertLogged( String name )
{
log.assertExactly(
inLog( this.getClass() ).info( format( "{plugin-%s} info line", name ) ),
inLog( this.getClass() ).warn( format( "{plugin-%s} warn line", name ) ),
inLog( this.getClass() ).error( format( "{plugin-%s} error line", name ) )
);
}

private class LoggingAuthPlugin extends LoggingAdapter implements AuthPlugin
{
@Override
public String name()
{
return "LoggingAuthPlugin";
}

@Override
public AuthInfo authenticateAndAuthorize( AuthToken authToken ) throws AuthenticationException
{
return null;
}
}

private class LoggingAuthenticationPlugin extends LoggingAdapter implements AuthenticationPlugin
{
@Override
public String name()
{
return "LoggingAuthenticationPlugin";
}

@Override
public AuthenticationInfo authenticate( AuthToken authToken ) throws AuthenticationException
{
return null;
}
}

private class LoggingAuthorizationPlugin extends LoggingAdapter implements AuthorizationPlugin
{
@Override
public String name()
{
return "LoggingAuthorizationPlugin";
}

@Override
public AuthorizationInfo authorize( Collection<PrincipalAndRealm> principals )
{
return null;
}
}

abstract class LoggingAdapter extends RealmLifecycle.Adapter
{
@Override
public void initialize( RealmOperations realmOperations ) throws Throwable
{
RealmOperations.Log log = realmOperations.log();
if ( log.isDebugEnabled() )
{
log.debug( "debug line" );
}
log.info( "info line" );
log.warn( "warn line" );
log.error( "error line" );
}
}
}

0 comments on commit 2ccb074

Please sign in to comment.