All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.security.BasicArtemisAuthModule Maven / Gradle / Ivy

There is a newer version: 4.10.9
Show newest version
package org.yamcs.security;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.activemq.artemis.core.security.CheckType;
import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamcs.ConfigurationException;
import org.yamcs.api.artemis.YamcsSession;

/**
 * Authenticates and authorises ActiveMQ sessions from configured realm.
 * 
 * See {@link Privilege} for information on authentication, authorisation and caching
 * 
 * A default user is used for anonymous (non-authenticated) connections.
 * Specify a default user (and associated roles) in hornetq-users.xml. If no
 * default user is configured, anonymous connections will be rejected.
 * 
 * @author atu
 *
 */
public class BasicArtemisAuthModule implements ActiveMQSecurityManager {
    static Logger log = LoggerFactory.getLogger(BasicArtemisAuthModule.class);
    private Map> configuredUserCache = new HashMap<>();
    /** If null (default), anonymous connections will be rejected. */
    private String defaultUser = null;
    final BasicAuthModule basicAuthModule;
    
    public BasicArtemisAuthModule() {
        AuthModule authModule = Privilege.getInstance().getAuthModule();
        if(!(authModule instanceof BasicAuthModule)) {
            throw new ConfigurationException("This Artemis auth manager only works with the BasicAuthModule configured in the priviles.yaml");
        }
        this.basicAuthModule = (BasicAuthModule)authModule;
    }
    /**
     * Determines if no restrictions should be applied to the specified user,
     * which can mean either that privileges are disabled (everyone has all
     * privilieges), or that the user is an in-process user.
     * 
     * Internal messaging user (in-vm user) is the only current super-user.
     * Null username or password always returns false if privileges enabled.
     * 
     * @param username
     * @param password
     * @return True if configured to not use privileges (see {@link Privilege})
     * 	or if username and password match a super user.
     */
    public boolean isSuperUser( String username, String password ) {
        if( !Privilege.usePrivileges ) {
            return true;
        }
        // Anonymous is never super user when using Privileges
        if( username == null || password == null ) {
            return false;
        }
        // Currently only server processes can be super-user
        return username.equals( YamcsSession.hornetqInvmUser ) && password.equals( YamcsSession.hornetqInvmPass );
    }
/*

    @Override
    public void addRole(String username, String role) {
        // Allow setting a default user from config, used for anonymous connections,
        if( username != null && username == defaultUser ) {
            if( configuredUserCache.containsKey( defaultUser ) ) {
                configuredUserCache.get(defaultUser).add( role );
                log.debug( "Default user '{}' given role '{}'.",username, role );
            }
        } else {
            log.debug( "addRole('{}','{}') called but will perform no function",username, role );
        }
    }

    @Override
    public void setDefaultUser(String username) {
        // Allow setting a default user from config, used for anonymous connections,
        if( defaultUser != null ) {
            configuredUserCache.remove( defaultUser );
        }
        defaultUser = username;
        configuredUserCache.put(defaultUser, new ArrayList());
        log.info( "Default user (used for anonymous connections) set to '{}'",username );
        log.warn( "Anonymous connections allowed, will be treated as user '{}'", username );
    }
*/
    @Override
    public boolean validateUser(String username, String password) {
        // Allow all? Looks for invm processes, or if privileges disabled.
        if( isSuperUser( username, password ) ) {
            return true;
        }

        // Anonymous user taken as default user...
        if( username == null ) {
            // If no default user, anonymous connections are not allowed.
            return ( defaultUser != null );
        }
        User user = basicAuthModule.getUser(new UsernamePasswordToken(username, password));
        if( user==null || !user.isAuthenticated()){
            return false;
        }
        log.info("User '{}' authenticated with {}", username, Privilege.getAuthModuleName());
        return true;
    }

    /**
     * @param configuredRoles - Set of roles configured for the component being accessed.
     * @param checkType - Permission being sought.
     */
    @Override
    public boolean validateUserAndRole(String username, String password, Set configuredRoles, CheckType checkType) {
        // Allow all? Looks for invm processes, or if privileges disabled.
        if( isSuperUser( username, password ) ) {
            return true;
        }

        // Anonymous user taken as default user if set
        if( username == null ) {
            if( defaultUser == null ) {
                return false;
            }
            // Default user is only in config, not in realm, so check perms now
            username = defaultUser;
            for( Role configuredRole : configuredRoles ) {
                if( configuredUserCache.get( defaultUser ).contains( configuredRole.getName() ) && checkType.hasRole( configuredRole ) ) {
                    return true;
                }
            }
        }

        // If required roles not configured, warn as configuration error
        if( configuredRoles == null ) {
            log.warn( "No roles configured, cannot validate '{}' for check '{}'", username, checkType );
            return false;
        }

        // Use configuration to set security-invalidation-interval and always
        // check authentication in this method.
        if( ! validateUser( username, password ) ) {
            return false;
        }

        Privilege p = Privilege.getInstance();
        UsernamePasswordToken userToken = new UsernamePasswordToken(username, password);
        for( Role configuredRole : configuredRoles ) {
            if(basicAuthModule.hasRole(userToken, configuredRole.getName() ) && checkType.hasRole( configuredRole ) ) {
                return true;
            }
        }

        log.trace( "User '{}' does not have any of '{}' for '{}'", username, configuredRoles, checkType );
        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy