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
public AuthManager newInstance( Config config, LogProvider logProvider )
{
InternalFlatFileRealm internalRealm = createInternalRealm( config, logProvider );

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
}

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

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 AuthenticationStrategy authenticationStrategy;
private final boolean authenticationEnabled;
private final boolean authorizationEnabled;
private final Map<String,SimpleRole> roles;

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

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

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

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

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

if ( authenticationEnabled )
ensureDefaultUsersAndRoles();
}

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

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

ShiroAuthToken shiroAuthToken = (ShiroAuthToken) token;

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

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

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

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

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

setContextFactory( contextFactory );
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

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

@Description( "Enable auth via a settings configurable LDAP authentication realm." )
public static final Setting<Boolean> ldap_auth_enabled =
setting( "dbms.security.ldap.enabled", BOOLEAN, "false" );
@Description( "Enable authorization via internal authorization provider." )
public static final Setting<Boolean> internal_authorization_enabled =
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." )
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." )
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" )
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." )
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" )
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" )
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();
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.init();
manager.start();
Expand Down
Expand Up @@ -45,7 +45,6 @@
*/
public class AuthScenariosIT extends AuthProcedureTestBase
{

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

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

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

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

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

// When
RunResult result = InterleavedRunner.interleave(
Expand Down
Expand Up @@ -64,7 +64,7 @@ public void setUp() throws Throwable
authStrategy = mock( AuthenticationStrategy.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.init();
userManager = manager.getUserManager();
Expand Down
Expand Up @@ -43,7 +43,6 @@ protected Consumer<Map<Setting<?>, String>> getSettingsFunction()
return settings -> {
settings.put( GraphDatabaseSettings.auth_enabled, "true" );
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.