Package org.geoserver.security.validation

Source Code of org.geoserver.security.validation.SecurityConfigValidator

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/

package org.geoserver.security.validation;

import static org.geoserver.security.validation.SecurityConfigException.*;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.security.GeoServerAuthenticationProvider;
import org.geoserver.security.GeoServerRoleService;
import org.geoserver.security.GeoServerSecurityFilterChain;
import org.geoserver.security.GeoServerSecurityFilterChainProxy;
import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.GeoServerSecurityProvider;
import org.geoserver.security.GeoServerUserGroupService;
import org.geoserver.security.HtmlLoginFilterChain;
import org.geoserver.security.MasterPasswordProvider;
import org.geoserver.security.RequestFilterChain;
import org.geoserver.security.ServiceLoginFilterChain;
import org.geoserver.security.VariableFilterChain;
import org.geoserver.security.config.PasswordPolicyConfig;
import org.geoserver.security.config.SecurityAuthProviderConfig;
import org.geoserver.security.config.SecurityManagerConfig;
import org.geoserver.security.config.SecurityNamedServiceConfig;
import org.geoserver.security.config.SecurityRoleServiceConfig;
import org.geoserver.security.config.SecurityUserGroupServiceConfig;
import org.geoserver.security.filter.GeoServerAuthenticationFilter;
import org.geoserver.security.filter.GeoServerSecurityFilter;
import org.geoserver.security.impl.GeoServerRole;
import org.geoserver.security.password.GeoServerPasswordEncoder;
import org.geoserver.security.password.MasterPasswordProviderConfig;
import org.geoserver.security.password.PasswordValidator;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.util.StringUtils;


public class SecurityConfigValidator extends AbstractSecurityValidator{

    public SecurityConfigValidator(GeoServerSecurityManager securityManager) {
        super(securityManager);
    }

    /**
     * Get the proper {@link SecurityConfigValidator} object
     *
     * @param serviceClass
     * @param className
     * @return
     */
    static public SecurityConfigValidator getConfigurationValiator(Class <?> serviceClass, String className)
            throws SecurityConfigException {
        GeoServerSecurityProvider prov = GeoServerSecurityProvider.getProvider(serviceClass, className);
        if (className == null)
            throw new SecurityConfigException(CLASSNAME_REQUIRED,new Object[]{});
       
        //TODO: remove the call to extensions, have teh security manager be passed in
        return prov.createConfigurationValidator(GeoServerExtensions.bean(GeoServerSecurityManager.class));
    }
   
   
    /**
     * Checks the {@link SecurityManagerConfig} object
     *
     * @param config
     * @param oldConfig
     * @throws SecurityConfigException
     */
    public void validateManagerConfig(SecurityManagerConfig config,
            SecurityManagerConfig oldConfig) throws SecurityConfigException{
       
        String encrypterName =config.getConfigPasswordEncrypterName();
        if (isNotEmpty(encrypterName)==false) {
            throw createSecurityException(PASSWORD_ENCODER_REQUIRED);
        }
       
        GeoServerPasswordEncoder encoder = null;
        try {
            encoder = manager.loadPasswordEncoder(config.getConfigPasswordEncrypterName());
        } catch (NoSuchBeanDefinitionException ex) {
            throw createSecurityException(INVALID_PASSWORD_ENCODER_$1, encrypterName);
        }
        if (encoder == null) {
            throw createSecurityException(INVALID_PASSWORD_ENCODER_$1, encrypterName);
        }

        if (!encoder.isReversible()) {
            throw createSecurityException(INVALID_PASSWORD_ENCODER_$1, encrypterName);
        }

        if (!manager.isStrongEncryptionAvailable()) {
            if (encoder!=null && encoder.isAvailableWithoutStrongCryptogaphy()==false) {
                throw createSecurityException(INVALID_STRONG_CONFIG_PASSWORD_ENCODER);
            }
        }
       
        String roleServiceName = config.getRoleServiceName();
        if (roleServiceName==null)
            roleServiceName="";
       
        try {
            if (manager.listRoleServices().contains(roleServiceName)==false)
                throw createSecurityException(ROLE_SERVICE_NOT_FOUND_$1, roleServiceName);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
       
        SortedSet<String> authProviders=null;
        try{
            authProviders =manager.listAuthenticationProviders();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        for (String authProvName : config.getAuthProviderNames()) {
            if (authProviders.contains(authProvName)==false)
                throw createSecurityException(AUTH_PROVIDER_NOT_FOUND_$1, authProvName);
        }
       
        // check the filter chain
       
       
        GeoServerSecurityFilterChain chain = config.getFilterChain();
        GeoServerSecurityFilterChain oldChain = oldConfig.getFilterChain();
        if (chain == null) {
            throw createSecurityException(SecurityConfigException.FILTER_CHAIN_NULL_ERROR);           
        }

        // check for remove
        for (RequestFilterChain oldRequestChain : oldChain.getRequestChains()) {
            if (chain.getRequestChainByName(oldRequestChain.getName())==null) {
                if (oldRequestChain.canBeRemoved()==false) {
                    throw createSecurityException(
                            SecurityConfigException.FILTER_CHAIN_NOT_REMOVEABLE_$1,oldRequestChain.getName());
                }
            }
        }
        // check for unique chain names
        for (RequestFilterChain requestChain : chain.getRequestChains()) {
            Set<String> chainNames = new HashSet<String> ();
            // valid name
            if (isNotEmpty(requestChain.getName())==false) {
                  throw createSecurityException(SecurityConfigException.FILTER_CHAIN_NAME_MANDATORY);
            }
            if (chainNames.contains(requestChain.getName())) {
                throw createSecurityException(
                        SecurityConfigException.FILTER_CHAIN_NAME_NOT_UNIQUE_$1,requestChain.getName());
            }
            chainNames.add(requestChain.getName());
        }
       
        for (RequestFilterChain requestChain : chain.getRequestChains()) {
            validateRequestFilterChain(requestChain);
        }
    }
   
    public void validateRequestFilterChain(RequestFilterChain requestChain) throws SecurityConfigException {
        if (isNotEmpty(requestChain.getName())==false) {
            throw createSecurityException(SecurityConfigException.FILTER_CHAIN_NAME_MANDATORY);
        }
       
        if (requestChain.getPatterns().isEmpty()) {
            throw createSecurityException(SecurityConfigException.PATTERN_LIST_EMPTY_$1,requestChain.getName());
        }
       
        GeoServerSecurityFilterChainProxy proxy = GeoServerExtensions.bean(GeoServerSecurityFilterChainProxy.class);
       
        String roleFilterName =  requestChain.getRoleFilterName();
        if (StringUtils.hasLength(roleFilterName)) {
            try {
                if (proxy.lookupFilter(roleFilterName)==null) {               
                    throw createSecurityException(SecurityConfigException.UNKNOWN_ROLE_FILTER_$2,requestChain.getName(),roleFilterName);
                }               
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
       
       

        if (requestChain instanceof VariableFilterChain) {
            if (requestChain.isDisabled()==false && requestChain.getFilterNames().isEmpty())
                throw createSecurityException(SecurityConfigException.FILTER_CHAIN_EMPTY_$1,requestChain.getName());
           
            String interceptorFilterName =  ((VariableFilterChain) requestChain).getInterceptorName();
            if (StringUtils.hasLength(interceptorFilterName)) {
                try {
                    if (proxy.lookupFilter(interceptorFilterName)==null) {               
                        throw createSecurityException(SecurityConfigException.UNKNOWN_INTERCEPTOR_FILTER_$2,requestChain.getName(),interceptorFilterName);
                    }
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            } else {
                throw createSecurityException(SecurityConfigException.INTERCEPTOR_FILTER_MANDATORY_$1,requestChain.getName());
            }
           
            String exceptionTranslationName =  ((VariableFilterChain) requestChain).getExceptionTranslationName();
            if (StringUtils.hasLength(exceptionTranslationName)) {
                try {
                    if (proxy.lookupFilter(exceptionTranslationName)==null) {               
                        throw createSecurityException(SecurityConfigException.UNKNOWN_EXCEPTION_FILTER_$2,requestChain.getName(),exceptionTranslationName);
                    }
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            } else {
                throw createSecurityException(SecurityConfigException.EXCEPTION_FILTER_MANDATORY_$1,requestChain.getName());
            }

           
            int index = requestChain.getFilterNames().indexOf(GeoServerSecurityFilterChain.ANONYMOUS_FILTER);
            if (index!=-1 && index != requestChain.getFilterNames().size()-1)
                throw createSecurityException(SecurityConfigException.ANONYMOUS_NOT_LAST_$1,requestChain.getName());
           
           
            for (String filterName : requestChain.getFilterNames()) {
                    GeoServerSecurityFilter filter=null;
                    try {
                        filter = (GeoServerSecurityFilter)proxy.lookupFilter(filterName);
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                    if (filter==null)
                        throw createSecurityException(SecurityConfigException.UNKNOWN_FILTER_$2,requestChain.getName(),filterName);
                    if (filter instanceof GeoServerAuthenticationFilter == false)
                        throw createSecurityException(SecurityConfigException.NOT_AN_AUTHENTICATION_FILTER_$2,requestChain.getName(),filterName);
                    GeoServerAuthenticationFilter authFilter = (GeoServerAuthenticationFilter) filter;
                   
                    if (requestChain instanceof HtmlLoginFilterChain && authFilter.applicableForHtml()==false) {       
                        throw createSecurityException(SecurityConfigException.NOT_A_HTML_AUTHENTICATION_FILTER_$2,requestChain.getName(),filterName);
                    }
                    if (requestChain instanceof ServiceLoginFilterChain && authFilter.applicableForServices()==false) {       
                        throw createSecurityException(SecurityConfigException.NOT_A_SERVICE_AUTHENTICATION_FILTER_$2,requestChain.getName(),filterName);
                    }
            }
        }
       
    }
   
    protected void checkExtensionPont(Class<?> extensionPoint, String className) throws SecurityConfigException{
        if (isNotEmpty(className)==false) {
            throw createSecurityException(CLASSNAME_REQUIRED);
        }
        Class<?> aClass = null;
        try {
            aClass=Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw createSecurityException(CLASS_NOT_FOUND_$1, className);
        }
       
        if (extensionPoint.isAssignableFrom(aClass)==false) {
            throw createSecurityException(CLASS_WRONG_TYPE_$2, extensionPoint,
                    className);
        }
    }
   
    protected void checkServiceName(Class<?> extensionPoint,String name) throws SecurityConfigException{
        if (name==null || name.isEmpty())
                throw createSecurityException(NAME_REQUIRED);                       
    }
   
    protected  SortedSet<String> getNamesFor(Class<?> extensionPoint) {
        try {
            if (extensionPoint==GeoServerUserGroupService.class)
                return manager.listUserGroupServices();
            if (extensionPoint==GeoServerRoleService.class)
                return manager.listRoleServices();
            if (extensionPoint==GeoServerAuthenticationProvider.class)
                return manager.listAuthenticationProviders();
            if (extensionPoint==AuthenticationProvider.class)
                return manager.listAuthenticationProviders();
            if (extensionPoint==GeoServerSecurityFilter.class)
                return manager.listFilters();
            if (extensionPoint==PasswordValidator.class)
                return manager.listPasswordValidators();
            if (extensionPoint==MasterPasswordProvider.class) {
                return  manager.listMasterPasswordProviders();
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        throw new RuntimeException("Unkwnown extension point: "+extensionPoint.getName());
    }
   
    public void validateAddNamedService(Class<?> extensionPoint,SecurityNamedServiceConfig config) throws SecurityConfigException{
        checkExtensionPont(extensionPoint, config.getClassName());
        checkServiceName(extensionPoint, config.getName());
        SortedSet<String> names= getNamesFor(extensionPoint);
        if (names.contains(config.getName()))
            throw createSecurityException(alreadyExistsErrorCode(extensionPoint), config.getName());
       
    }
   
    public void validateModifiedNamedService(Class<?> extensionPoint,SecurityNamedServiceConfig config) throws SecurityConfigException{
        checkExtensionPont(extensionPoint, config.getClassName());
        checkServiceName(extensionPoint, config.getName());
        SortedSet<String> names= getNamesFor(extensionPoint);
        if (names.contains(config.getName())==false)
            throw createSecurityException(notFoundErrorCode(extensionPoint),config.getName());
       
    }

       
    public void validateRemoveNamedService(Class<?> extensionPoint,SecurityNamedServiceConfig config) throws SecurityConfigException{
        checkServiceName(extensionPoint, config.getName());
    }
   
    public void validateAddUserGroupService(SecurityUserGroupServiceConfig config) throws SecurityConfigException{
        validateAddNamedService(GeoServerUserGroupService.class, config);       
        validate(config);
    }
   
    public void validateAddRoleService(SecurityRoleServiceConfig config) throws SecurityConfigException{
        validateAddNamedService(GeoServerRoleService.class, config);
        validate(config);
    }

    public void validateAddPasswordPolicy(PasswordPolicyConfig config) throws SecurityConfigException{
        validateAddNamedService(PasswordValidator.class, config);
        validate(config);
    }
   
   
    public void validateAddAuthProvider(SecurityAuthProviderConfig config) throws SecurityConfigException{
        validateAddNamedService(GeoServerAuthenticationProvider.class, config);
        validate(config);
    }

    public void validateAddFilter(SecurityNamedServiceConfig config) throws SecurityConfigException{
        validateAddNamedService(GeoServerSecurityFilter.class, config);       
    }

    public void validateAddMasterPasswordProvider(MasterPasswordProviderConfig config) throws SecurityConfigException {
        validateAddNamedService(MasterPasswordProvider.class, config);
        validate(config);
    }

    public void validateModifiedUserGroupService(SecurityUserGroupServiceConfig config,SecurityUserGroupServiceConfig oldConfig) throws SecurityConfigException{
        validateModifiedNamedService(GeoServerUserGroupService.class, config);
        validate(config);
    }
   
    public void validateModifiedRoleService(SecurityRoleServiceConfig config,SecurityRoleServiceConfig oldConfig) throws SecurityConfigException{
        validateModifiedNamedService(GeoServerRoleService.class, config);
        validate(config);
    }

    public void validateModifiedPasswordPolicy(PasswordPolicyConfig config,PasswordPolicyConfig oldConfig) throws SecurityConfigException{
        validateModifiedNamedService(PasswordValidator.class, config);
        validate(config);
    }
   
    public void validateModifiedAuthProvider(SecurityAuthProviderConfig config,SecurityAuthProviderConfig oldconfig) throws SecurityConfigException{
        validateModifiedNamedService(GeoServerAuthenticationProvider.class, config);
        validate(config);       
    }

    public void validateModifiedFilter(SecurityNamedServiceConfig config,SecurityNamedServiceConfig oldConfig) throws SecurityConfigException{
        validateModifiedNamedService(GeoServerSecurityFilter.class, config);       
    }

    public void validateModifiedMasterPasswordProvider(MasterPasswordProviderConfig config,
        MasterPasswordProviderConfig oldConfig) throws SecurityConfigException {
        validateModifiedNamedService(MasterPasswordProvider.class, config);
        validate(config);
    }

    public void validateRemoveUserGroupService(SecurityUserGroupServiceConfig config) throws SecurityConfigException{
        validateRemoveNamedService(GeoServerUserGroupService.class, config);
        try {
            for (String name: manager.listAuthenticationProviders()) {
                SecurityAuthProviderConfig authConfig =
                        manager.loadAuthenticationProviderConfig(name);
                String userGroupService=authConfig.getUserGroupServiceName();
                if (isNotEmpty(userGroupService)) {
                    if (authConfig.getUserGroupServiceName().equals(config.getName()))
                        throw createSecurityException(USERGROUP_SERVICE_ACTIVE_$2, config.getName(),authConfig.getName());
                }   
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
       
    }
   
    public void validateRemoveRoleService(SecurityRoleServiceConfig config) throws SecurityConfigException{
        validateRemoveNamedService(GeoServerRoleService.class, config);
        if (manager.getActiveRoleService().getName().equals(config.getName())) {
                    throw createSecurityException(ROLE_SERVICE_ACTIVE_$1, config.getName());
                }
    }

    public void validateRemovePasswordPolicy(PasswordPolicyConfig config) throws SecurityConfigException{
        validateRemoveNamedService(PasswordValidator.class, config);
       
        if (PasswordValidator.MASTERPASSWORD_NAME.equals(config.getName()))
                throw createSecurityException(PASSWD_POLICY_MASTER_DELETE);
               
        try {
            for (String name: manager.listUserGroupServices()) {
                SecurityUserGroupServiceConfig ugConfig =
                        manager.loadUserGroupServiceConfig(name);
                if (ugConfig.getPasswordPolicyName().equals(config.getName()))
                    throw createSecurityException(PASSWD_POLICY_ACTIVE_$2, config.getName(),ugConfig.getName());
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
   
    public void validateRemoveAuthProvider(SecurityAuthProviderConfig config) throws SecurityConfigException{
        validateRemoveNamedService(GeoServerAuthenticationProvider.class, config);       
        for (GeoServerAuthenticationProvider prov :manager.getAuthenticationProviders()) {
            if (prov.getName().equals(config.getName()))
                throw createSecurityException(AUTH_PROVIDER_ACTIVE_$1, config.getName());
        }
    }

    public void validateRemoveFilter(SecurityNamedServiceConfig config) throws SecurityConfigException{
        validateRemoveNamedService(GeoServerSecurityFilter.class, config);
       
        List<String> patterns =
            manager.getSecurityConfig().getFilterChain().patternsForFilter(config.getClassName(),false);
        if (patterns.isEmpty()==false) {
            throw createSecurityException(SecurityConfigException.FILTER_STILL_USED,
                    config.getName(),
                    StringUtils.arrayToCommaDelimitedString(patterns.toArray()));
        }       
    }

    public void validateRemoveMasterPasswordProvider(MasterPasswordProviderConfig config)
            throws SecurityConfigException {
        validateRemoveNamedService(MasterPasswordProvider.class, config);
    }

    public void validate(SecurityAuthProviderConfig config) throws SecurityConfigException {
        if (isNotEmpty(config.getUserGroupServiceName())) {
            if (getNamesFor(GeoServerUserGroupService.class).
                    contains(config.getUserGroupServiceName())==false)
                    throw createSecurityException(USERGROUP_SERVICE_NOT_FOUND_$1,
                            config.getUserGroupServiceName() );
        }       
    }
   
    public void validate(SecurityRoleServiceConfig config) throws SecurityConfigException {
        for (GeoServerRole systemRole : GeoServerRole.SystemRoles) {
            if (systemRole.getAuthority().equals(config.getAdminRoleName()))
                throw createSecurityException(RESERVED_ROLE_NAME,systemRole.getAuthority());
            if (systemRole.getAuthority().equals(config.getGroupAdminRoleName()))
                throw createSecurityException(RESERVED_ROLE_NAME,systemRole.getAuthority());
        }     
    }

    public void validate(SecurityUserGroupServiceConfig config) throws SecurityConfigException {
        String encoderName =config.getPasswordEncoderName();
        GeoServerPasswordEncoder encoder = null;
        if (isNotEmpty(encoderName)) {
            try {
                encoder = manager.loadPasswordEncoder(encoderName);
            } catch (NoSuchBeanDefinitionException ex) {
                throw createSecurityException(INVALID_CONFIG_PASSWORD_ENCODER_$1, encoderName);
            }
            if (encoder == null) {
                throw createSecurityException(INVALID_CONFIG_PASSWORD_ENCODER_$1, encoderName);
            }
        } else {
            throw createSecurityException(PASSWD_ENCODER_REQUIRED_$1, config.getName());
        }
       
        if (!manager.isStrongEncryptionAvailable()) {
            if (encoder!=null && encoder.isAvailableWithoutStrongCryptogaphy()==false) {
                throw createSecurityException(INVALID_STRONG_PASSWORD_ENCODER);
            }
        }
       
        String policyName= config.getPasswordPolicyName();
        if (isNotEmpty(policyName)==false) {
            throw createSecurityException(PASSWD_POLICY_REQUIRED_$1, config.getName());
        }
       
        if (getNamesFor(PasswordValidator.class).contains(policyName)==false) {
            throw createSecurityException(PASSWD_POLICY_NOT_FOUND_$1,policyName);
        }
    }
   
    public void validate(PasswordPolicyConfig config) throws SecurityConfigException {
        if (config.getMinLength() < 0)
            throw createSecurityException(INVALID_MIN_LENGTH);
        if (config.getMaxLength() !=- 1) {
            if (config.getMinLength()>config.getMaxLength())
                throw createSecurityException(INVALID_MAX_LENGTH);
        }
    }

    public void validate(MasterPasswordProviderConfig config) throws SecurityConfigException {
    }

    protected String alreadyExistsErrorCode(Class<?> extPoint) {
        if (GeoServerAuthenticationProvider.class==extPoint)
            return AUTH_PROVIDER_ALREADY_EXISTS_$1;
        if (PasswordValidator.class==extPoint)
            return PASSWD_POLICY_ALREADY_EXISTS_$1;
        if (GeoServerRoleService.class==extPoint)
            return ROLE_SERVICE_ALREADY_EXISTS_$1;
        if (GeoServerUserGroupService.class==extPoint)
            return USERGROUP_SERVICE_ALREADY_EXISTS_$1;
        if (GeoServerSecurityFilter.class==extPoint)
            return AUTH_FILTER_ALREADY_EXISTS_$1;
        throw new RuntimeException("Unknown extension point: "+extPoint.getName());
    }

    protected String notFoundErrorCode(Class<?> extPoint) {
        if (GeoServerAuthenticationProvider.class==extPoint)
            return AUTH_PROVIDER_NOT_FOUND_$1;
        if (PasswordValidator.class==extPoint)
            return PASSWD_POLICY_NOT_FOUND_$1;
        if (GeoServerRoleService.class==extPoint)
            return ROLE_SERVICE_NOT_FOUND_$1;
        if (GeoServerUserGroupService.class==extPoint)
            return USERGROUP_SERVICE_NOT_FOUND_$1;
        if (GeoServerSecurityFilter.class==extPoint)
            return AUTH_FILTER_NOT_FOUND_$1;
        throw new RuntimeException("Unknown extension point: "+extPoint.getName());
    }

    /**
     * Helper method for creating a proper
     * {@link SecurityConfigException} object
     */
    protected SecurityConfigException createSecurityException (String errorid, Object ...args) {
        return new SecurityConfigException(errorid,args);
    }
}
TOP

Related Classes of org.geoserver.security.validation.SecurityConfigValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.