Skip to content

Commit

Permalink
Separate settings for authentication and authorization
Browse files Browse the repository at this point in the history
Authentication and authorization can be enabled separately for the realms
internal, ldap and plugin.

- Remove temporary authorization in LdapRealm (to be implemented separately)
- Add integration test for ldap authentication + internal authorization
  • Loading branch information
henriknyman committed Jun 27, 2016
1 parent 8b0d232 commit 2704e61
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 41 deletions.
Expand Up @@ -57,19 +57,26 @@ public EnterpriseAuthManagerFactory()
@Override @Override
public AuthManager newInstance( Config config, LogProvider logProvider ) public AuthManager newInstance( Config config, LogProvider logProvider )
{ {
InternalFlatFileRealm internalRealm = createInternalRealm( config, logProvider );

List<Realm> realms = new ArrayList<>( 2 ); List<Realm> realms = new ArrayList<>( 2 );


realms.add( internalRealm ); // We always create the internal realm as it is our only UserManager implementation
InternalFlatFileRealm internalRealm = createInternalRealm( config, logProvider );

if ( config.get( SecuritySettings.internal_authentication_enabled ) ||
config.get( SecuritySettings.internal_authorization_enabled ) )
{
realms.add( internalRealm );
}


if ( config.get( SecuritySettings.external_auth_enabled ) ) if ( config.get( SecuritySettings.ldap_authentication_enabled ) ||
config.get( SecuritySettings.ldap_authorization_enabled ) )
{ {
if ( config.get( SecuritySettings.ldap_auth_enabled ) ) realms.add( new LdapRealm( config ) );
{ }
realms.add( new LdapRealm( config ) );
}


if ( config.get( SecuritySettings.plugin_authentication_enabled ) ||
config.get( SecuritySettings.plugin_authorization_enabled ) )
{
// TODO: Load pluggable realms // TODO: Load pluggable realms
} }


Expand Down Expand Up @@ -101,6 +108,7 @@ private InternalFlatFileRealm createInternalRealm( Config config, LogProvider lo
AuthenticationStrategy authenticationStrategy = new RateLimitedAuthenticationStrategy( systemUTC(), 3 ); AuthenticationStrategy authenticationStrategy = new RateLimitedAuthenticationStrategy( systemUTC(), 3 );


return new InternalFlatFileRealm( userRepository, roleRepository, passwordPolicy, authenticationStrategy, return new InternalFlatFileRealm( userRepository, roleRepository, passwordPolicy, authenticationStrategy,
true ); config.get( SecuritySettings.internal_authentication_enabled ),
config.get( SecuritySettings.internal_authorization_enabled ) );
} }
} }
Expand Up @@ -92,11 +92,12 @@ public Collection<Permission> resolvePermissionsInRole( String roleString )
private final PasswordPolicy passwordPolicy; private final PasswordPolicy passwordPolicy;
private final AuthenticationStrategy authenticationStrategy; private final AuthenticationStrategy authenticationStrategy;
private final boolean authenticationEnabled; private final boolean authenticationEnabled;
private final boolean authorizationEnabled;
private final Map<String,SimpleRole> roles; private final Map<String,SimpleRole> roles;


public InternalFlatFileRealm( UserRepository userRepository, RoleRepository roleRepository, public InternalFlatFileRealm( UserRepository userRepository, RoleRepository roleRepository,
PasswordPolicy passwordPolicy, AuthenticationStrategy authenticationStrategy, PasswordPolicy passwordPolicy, AuthenticationStrategy authenticationStrategy,
boolean authenticationEnabled ) boolean authenticationEnabled, boolean authorizationEnabled )
{ {
super(); super();


Expand All @@ -105,12 +106,19 @@ public InternalFlatFileRealm( UserRepository userRepository, RoleRepository role
this.passwordPolicy = passwordPolicy; this.passwordPolicy = passwordPolicy;
this.authenticationStrategy = authenticationStrategy; this.authenticationStrategy = authenticationStrategy;
this.authenticationEnabled = authenticationEnabled; this.authenticationEnabled = authenticationEnabled;
this.authorizationEnabled = authenticationEnabled;
setCredentialsMatcher( new AllowAllCredentialsMatcher() ); setCredentialsMatcher( new AllowAllCredentialsMatcher() );
setRolePermissionResolver( rolePermissionResolver ); setRolePermissionResolver( rolePermissionResolver );


roles = new PredefinedRolesBuilder().buildRoles(); roles = new PredefinedRolesBuilder().buildRoles();
} }


public InternalFlatFileRealm( UserRepository userRepository, RoleRepository roleRepository,
PasswordPolicy passwordPolicy, AuthenticationStrategy authenticationStrategy )
{
this( userRepository, roleRepository, passwordPolicy, authenticationStrategy, true, true );
}

@Override @Override
public void initialize() throws Throwable public void initialize() throws Throwable
{ {
Expand All @@ -124,7 +132,12 @@ public void start() throws Throwable
userRepository.start(); userRepository.start();
roleRepository.start(); roleRepository.start();


if ( authenticationEnabled ) ensureDefaultUsersAndRoles();
}

private void ensureDefaultUsersAndRoles() throws IOException, IllegalCredentialsException
{
if ( authenticationEnabled || authorizationEnabled )
{ {
if ( numberOfRoles() == 0 ) if ( numberOfRoles() == 0 )
{ {
Expand Down Expand Up @@ -177,6 +190,11 @@ public boolean supports( AuthenticationToken token )
@Override @Override
protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals ) throws AuthenticationException protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals ) throws AuthenticationException
{ {
if ( !authorizationEnabled )
{
return null;
}

String username = (String) getAvailablePrincipal( principals ); String username = (String) getAvailablePrincipal( principals );
if ( username == null ) if ( username == null )
{ {
Expand All @@ -203,6 +221,11 @@ protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principa
@Override @Override
protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token ) throws AuthenticationException protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token ) throws AuthenticationException
{ {
if ( !authenticationEnabled )
{
return null;
}

ShiroAuthToken shiroAuthToken = (ShiroAuthToken) token; ShiroAuthToken shiroAuthToken = (ShiroAuthToken) token;


String username; String username;
Expand Down
Expand Up @@ -23,7 +23,6 @@
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission; import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.SimpleRole; import org.apache.shiro.authz.SimpleRole;
import org.apache.shiro.authz.permission.RolePermissionResolver; import org.apache.shiro.authz.permission.RolePermissionResolver;
import org.apache.shiro.realm.ldap.JndiLdapContextFactory; import org.apache.shiro.realm.ldap.JndiLdapContextFactory;
Expand All @@ -44,19 +43,33 @@
*/ */
public class LdapRealm extends JndiLdapRealm public class LdapRealm extends JndiLdapRealm
{ {
private boolean authenticationEnabled;
private boolean authorizationEnabled;

public LdapRealm( Config config ) public LdapRealm( Config config )
{ {
super(); super();
setRolePermissionResolver( rolePermissionResolver ); setRolePermissionResolver( rolePermissionResolver );
configureRealm( config ); configureRealm( config );
} }


@Override
protected AuthenticationInfo queryForAuthenticationInfo( AuthenticationToken token,
LdapContextFactory ldapContextFactory )
throws NamingException
{
return authenticationEnabled ? super.queryForAuthenticationInfo( token, ldapContextFactory ) : null;
}

@Override @Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException LdapContextFactory ldapContextFactory) throws NamingException
{ {
// TODO: This is just temporary if ( authorizationEnabled )
return new SimpleAuthorizationInfo( Collections.singleton( PredefinedRolesBuilder.READER ) ); {
// TODO: Implement LDAP authorization
}
return null;
} }


@Override @Override
Expand Down Expand Up @@ -96,5 +109,8 @@ private void configureRealm( Config config )


setContextFactory( contextFactory ); setContextFactory( contextFactory );
setUserDnTemplate( config.get( SecuritySettings.ldap_user_dn_template ) ); setUserDnTemplate( config.get( SecuritySettings.ldap_user_dn_template ) );

authenticationEnabled = config.get( SecuritySettings.ldap_authentication_enabled );
authorizationEnabled = config.get( SecuritySettings.ldap_authorization_enabled );
} }
} }
Expand Up @@ -37,35 +37,51 @@ public class SecuritySettings
{ {
@SuppressWarnings( "unused" ) // accessed by reflection @SuppressWarnings( "unused" ) // accessed by reflection


@Description( "Enable auth via external authentication providers." ) @Description( "Enable authentication via internal authentication provider." )
public static final Setting<Boolean> external_auth_enabled = public static final Setting<Boolean> internal_authentication_enabled =
setting( "dbms.security.external_auth_enabled", BOOLEAN, "false" ); setting( "dbms.security.realms.internal.authentication_enabled", BOOLEAN, "true" );


@Description( "Enable auth via a settings configurable LDAP authentication realm." ) @Description( "Enable authorization via internal authorization provider." )
public static final Setting<Boolean> ldap_auth_enabled = public static final Setting<Boolean> internal_authorization_enabled =
setting( "dbms.security.ldap.enabled", BOOLEAN, "false" ); setting( "dbms.security.realms.internal.authorization_enabled", BOOLEAN, "true" );

@Description( "Enable authentication via settings configurable LDAP authentication realm." )
public static final Setting<Boolean> ldap_authentication_enabled =
setting( "dbms.security.realms.ldap.authentication_enabled", BOOLEAN, "false" );

@Description( "Enable authotization via settings configurable LDAP authorization realm." )
public static final Setting<Boolean> ldap_authorization_enabled =
setting( "dbms.security.realms.ldap.authorization_enabled", BOOLEAN, "false" );

@Description( "Enable authentication via plugin authentication realms." )
public static final Setting<Boolean> plugin_authentication_enabled =
setting( "dbms.security.realms.plugin.authentication_enabled", BOOLEAN, "false" );

@Description( "Enable authotization via plugin authorization realms." )
public static final Setting<Boolean> plugin_authorization_enabled =
setting( "dbms.security.realms.plugin.authorization_enabled", BOOLEAN, "false" );


@Description( "Hostname and port of LDAP server to use for authentication and authorization." ) @Description( "Hostname and port of LDAP server to use for authentication and authorization." )
public static final Setting<HostnamePort> ldap_server = public static final Setting<HostnamePort> ldap_server =
setting( "dbms.security.ldap.host", HOSTNAME_PORT, "0.0.0.0:389" ); setting( "dbms.security.realms.ldap.host", HOSTNAME_PORT, "0.0.0.0:389" );


@Description( "Authentication mechanism." ) @Description( "Authentication mechanism." )
public static final Setting<String> ldap_auth_mechanism = public static final Setting<String> ldap_auth_mechanism =
setting( "dbms.security.ldap.auth_mechanism", STRING, "simple" ); setting( "dbms.security.realms.ldap.auth_mechanism", STRING, "simple" );


@Description( "Referral" ) @Description( "Referral" )
public static final Setting<String> ldap_referral = public static final Setting<String> ldap_referral =
setting( "dbms.security.ldap.referral", STRING, "follow" ); setting( "dbms.security.realms.ldap.referral", STRING, "follow" );


@Description( "User DN template." ) @Description( "User DN template." )
public static final Setting<String> ldap_user_dn_template = public static final Setting<String> ldap_user_dn_template =
setting( "dbms.security.ldap.user_dn_template", STRING, "uid={0},ou=users,dc=example,dc=com" ); setting( "dbms.security.realms.ldap.user_dn_template", STRING, "uid={0},ou=users,dc=example,dc=com" );


@Description( "System username" ) @Description( "System username" )
public static final Setting<String> ldap_system_username = public static final Setting<String> ldap_system_username =
setting( "dbms.security.ldap.system_username", STRING, NO_DEFAULT ); setting( "dbms.security.realms.ldap.system_username", STRING, NO_DEFAULT );


@Description( "System password" ) @Description( "System password" )
public static final Setting<String> ldap_system_password = public static final Setting<String> ldap_system_password =
setting( "dbms.security.ldap.system_password", STRING, NO_DEFAULT ); setting( "dbms.security.realms.ldap.system_password", STRING, NO_DEFAULT );
} }
Expand Up @@ -80,7 +80,7 @@ public void setUp() throws Throwable
{ {
db = (GraphDatabaseAPI) new TestEnterpriseGraphDatabaseFactory().newImpermanentDatabase(); db = (GraphDatabaseAPI) new TestEnterpriseGraphDatabaseFactory().newImpermanentDatabase();
internalRealm = new InternalFlatFileRealm( new InMemoryUserRepository(), new InMemoryRoleRepository(), internalRealm = new InternalFlatFileRealm( new InMemoryUserRepository(), new InMemoryRoleRepository(),
new BasicPasswordPolicy(), new RateLimitedAuthenticationStrategy( systemUTC(), 3 ), true ); new BasicPasswordPolicy(), new RateLimitedAuthenticationStrategy( systemUTC(), 3 ) );
manager = new MultiRealmAuthManager( internalRealm, Collections.singletonList( internalRealm ) ); manager = new MultiRealmAuthManager( internalRealm, Collections.singletonList( internalRealm ) );
manager.init(); manager.init();
manager.start(); manager.start();
Expand Down
Expand Up @@ -45,7 +45,6 @@
*/ */
public class AuthScenariosIT extends AuthProcedureTestBase public class AuthScenariosIT extends AuthProcedureTestBase
{ {

//---------- User creation ----------- //---------- User creation -----------


/* /*
Expand Down
Expand Up @@ -120,7 +120,7 @@ public void addUserToRoleShouldBeAtomic() throws Exception
CodePosition codePosition = getCodePositionAfterCall( "addUserToRole", "getUserByName" ); CodePosition codePosition = getCodePositionAfterCall( "addUserToRole", "getUserByName" );


InternalFlatFileRealm realm = new InternalFlatFileRealm( userRepository, roleRepository, passwordPolicy, InternalFlatFileRealm realm = new InternalFlatFileRealm( userRepository, roleRepository, passwordPolicy,
authenticationStrategy, true ); authenticationStrategy );


// When // When
RunResult result = InterleavedRunner.interleave( RunResult result = InterleavedRunner.interleave(
Expand All @@ -143,7 +143,7 @@ public void deleteUserShouldBeAtomic() throws Exception
CodePosition codePosition = getCodePositionAfterCall( "deleteUser", "getUserByName" ); CodePosition codePosition = getCodePositionAfterCall( "deleteUser", "getUserByName" );


InternalFlatFileRealm realm = new InternalFlatFileRealm( userRepository, roleRepository, passwordPolicy, InternalFlatFileRealm realm = new InternalFlatFileRealm( userRepository, roleRepository, passwordPolicy,
authenticationStrategy, true ); authenticationStrategy );


// When // When
RunResult result = InterleavedRunner.interleave( RunResult result = InterleavedRunner.interleave(
Expand Down
Expand Up @@ -64,7 +64,7 @@ public void setUp() throws Throwable
authStrategy = mock( AuthenticationStrategy.class ); authStrategy = mock( AuthenticationStrategy.class );
passwordPolicy = mock( PasswordPolicy.class ); passwordPolicy = mock( PasswordPolicy.class );


internalFlatFileRealm = new InternalFlatFileRealm( users, roles, passwordPolicy, authStrategy, true ); internalFlatFileRealm = new InternalFlatFileRealm( users, roles, passwordPolicy, authStrategy );
manager = new MultiRealmAuthManager( internalFlatFileRealm, Collections.singleton( internalFlatFileRealm )); manager = new MultiRealmAuthManager( internalFlatFileRealm, Collections.singleton( internalFlatFileRealm ));
manager.init(); manager.init();
userManager = manager.getUserManager(); userManager = manager.getUserManager();
Expand Down
Expand Up @@ -43,7 +43,6 @@ protected Consumer<Map<Setting<?>, String>> getSettingsFunction()
return settings -> { return settings -> {
settings.put( GraphDatabaseSettings.auth_enabled, "true" ); settings.put( GraphDatabaseSettings.auth_enabled, "true" );
settings.put( GraphDatabaseSettings.auth_manager, "enterprise-auth-manager" ); settings.put( GraphDatabaseSettings.auth_manager, "enterprise-auth-manager" );
settings.put( SecuritySettings.external_auth_enabled, "false" );
}; };
} }
} }

0 comments on commit 2704e61

Please sign in to comment.