Package org.uberfire.security.server

Source Code of org.uberfire.security.server.UberFireSecurityFilter

/*
* Copyright 2012 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.uberfire.security.server;

import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static org.uberfire.security.server.SecurityConstants.AUTHZ_MANAGER_KEY;
import static org.uberfire.security.server.SecurityConstants.AUTH_FORCE_URL;
import static org.uberfire.security.server.SecurityConstants.AUTH_MANAGER_KEY;
import static org.uberfire.security.server.SecurityConstants.AUTH_PROVIDER_KEY;
import static org.uberfire.security.server.SecurityConstants.AUTH_REMEMBER_ME_SCHEME_KEY;
import static org.uberfire.security.server.SecurityConstants.AUTH_SCHEME_KEY;
import static org.uberfire.security.server.SecurityConstants.COOKIE_NAME_KEY;
import static org.uberfire.security.server.SecurityConstants.FORM;
import static org.uberfire.security.server.SecurityConstants.LOGOUT_URI;
import static org.uberfire.security.server.SecurityConstants.RESOURCE_MANAGER_CONFIG_KEY;
import static org.uberfire.security.server.SecurityConstants.RESOURCE_MANAGER_KEY;
import static org.uberfire.security.server.SecurityConstants.ROLE_DECISION_MANAGER_KEY;
import static org.uberfire.security.server.SecurityConstants.ROLE_PROVIDER_KEY;
import static org.uberfire.security.server.SecurityConstants.SUBJECT_PROPERTIES_PROVIDER_KEY;
import static org.uberfire.security.server.SecurityConstants.URL_ACCESS_DECISION_MANAGER_KEY;
import static org.uberfire.security.server.SecurityConstants.URL_VOTING_MANAGER_KEY;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.uberfire.security.ResourceManager;
import org.uberfire.security.SecurityContext;
import org.uberfire.security.SecurityManager;
import org.uberfire.security.Subject;
import org.uberfire.security.auth.AuthenticationException;
import org.uberfire.security.auth.AuthenticationManager;
import org.uberfire.security.auth.AuthenticationProvider;
import org.uberfire.security.auth.AuthenticationScheme;
import org.uberfire.security.auth.RoleProvider;
import org.uberfire.security.auth.SubjectPropertiesProvider;
import org.uberfire.security.authz.AuthorizationManager;
import org.uberfire.security.authz.ResourceDecisionManager;
import org.uberfire.security.authz.RoleDecisionManager;
import org.uberfire.security.authz.VotingStrategy;
import org.uberfire.security.impl.authz.ConsensusBasedVoter;
import org.uberfire.security.server.auth.CookieStorage;
import org.uberfire.security.server.auth.FormAuthenticationScheme;
import org.uberfire.security.server.auth.HttpBasicAuthenticationScheme;
import org.uberfire.security.server.auth.HttpSessionStorage;
import org.uberfire.security.server.auth.RememberMeCookieAuthScheme;
import org.uberfire.security.server.cdi.SecurityFactory;

public class UberFireSecurityFilter implements Filter {

    private final Logger LOG = LoggerFactory.getLogger( UberFireSecurityFilter.class );
    private SecurityManager securityManager = null;

    @Override
    public void init( final FilterConfig filterConfig )
            throws ServletException {

        final Map<String, String> options = buildOptions( filterConfig );

        final CookieStorage cookieStorage = getCookieStorage( options );
        final AuthenticationScheme basicAuthScheme = new HttpBasicAuthenticationScheme();
        final AuthenticationScheme rememberMeAuthScheme = getRememberMeAuthScheme( options, cookieStorage );
        final String forceURL = getForceURL( options );
        final AuthenticationScheme authScheme = getAuthenticationScheme( options );
        final AuthenticationManager authManager = getAuthenticationManager( options );
        final AuthenticationProvider authProvider = getAuthenticationProvider( options );
        final ResourceManager resourceManager = getResourceManager( options );
        final AuthorizationManager authzManager = getAuthorizationManager( options );
        final VotingStrategy urlVotingStrategy = getURLVotingStrategy( options );
        final ResourceDecisionManager accessDecisionManager = getURLAccessDecisionManager( options );
        final RoleDecisionManager roleDecisionManager = getRoleDecisionManager( options );
        final RoleProvider roleProvider = getRoleProvider( options );
        final SubjectPropertiesProvider propertiesProvider = getPropertiesProvider( options );

        this.securityManager = HttpSecurityManagerImpl.newBuilder()
                .addAuthManager( authManager )
                .addAuthScheme( basicAuthScheme )
                .addAuthScheme( rememberMeAuthScheme )
                .addAuthScheme( authScheme )
                .addForceURL( forceURL )
                .addAuthProvider( authProvider )
                .addAuthenticatedStorageProvider( new HttpSessionStorage() )
                .addAuthenticatedStorageProvider( cookieStorage )
                .addRoleProvider( roleProvider )
                .addSubjectPropertiesProvider( propertiesProvider )
                .addAuthzManager( authzManager )
                .addVotingStrategy( urlVotingStrategy )
                .addAccessDecisionManager( accessDecisionManager )
                .addResourceManager( resourceManager )
                .addRoleDecisionManager( roleDecisionManager )
                .loadAvailableAuthenticationSources()
                .build( options );

        LOG.debug("Starting security manager with the following configuration:\n" + securityManager);
        securityManager.start();
    }

    private AuthenticationScheme getRememberMeAuthScheme( final Map<String, String> options,
                                                          final CookieStorage cookieStorage ) {
        if ( hasRememerMe( options ) ) {
            return new RememberMeCookieAuthScheme( cookieStorage );
        }

        return null;
    }

    private boolean hasRememerMe( final Map<String, String> options ) {
        final String rememberMe = options.get( AUTH_REMEMBER_ME_SCHEME_KEY );

        return rememberMe == null || rememberMe.trim().equalsIgnoreCase( "enabled" );
    }

    private String getForceURL( final Map<String, String> options ) {
        final String redirectURL = options.get( AUTH_FORCE_URL );

        if ( redirectURL == null ) {
            return null;
        }

        return redirectURL.trim();
    }

    private Map<String, String> buildOptions( FilterConfig filterConfig ) {
        final Map<String, String> result = new HashMap<String, String>();

        final Enumeration initParams = filterConfig.getInitParameterNames();
        while ( initParams.hasMoreElements() ) {
            final String name = (String) initParams.nextElement();
            final String value = filterConfig.getInitParameter( name );
            if ( !value.trim().isEmpty() ) {
                result.put( name, value );
            }
        }

        final Enumeration servletInitParams = filterConfig.getServletContext().getInitParameterNames();
        while ( servletInitParams.hasMoreElements() ) {
            final String name = (String) servletInitParams.nextElement();
            final String value = filterConfig.getServletContext().getInitParameter( name );
            if ( !value.trim().isEmpty() ) {
                result.put( name, value );
            }
        }

        return result;
    }

    private CookieStorage getCookieStorage( final Map<String, String> options ) {
        if ( hasRememerMe( options ) ) {
            final String cookieName = options.get( COOKIE_NAME_KEY );
            if ( cookieName == null || cookieName.trim().isEmpty() ) {
                throw new RuntimeException( "Can't find cookie id." );
            }
            return new CookieStorage( cookieName );
        }
        return null;
    }

    private RoleProvider getRoleProvider( final Map<String, String> options ) {
        final String roleProvider = options.get( ROLE_PROVIDER_KEY );

        return loadConfigClazz( roleProvider, RoleProvider.class );
    }

    private SubjectPropertiesProvider getPropertiesProvider( final Map<String, String> options ) {
        final String propertiesProvider = options.get( SUBJECT_PROPERTIES_PROVIDER_KEY );

        return loadConfigClazz( propertiesProvider, SubjectPropertiesProvider.class );
    }

    private RoleDecisionManager getRoleDecisionManager( final Map<String, String> options ) {
        final String roleManager = options.get( ROLE_DECISION_MANAGER_KEY );

        return loadConfigClazz( roleManager, RoleDecisionManager.class );
    }

    private ResourceDecisionManager getURLAccessDecisionManager( final Map<String, String> options ) {
        final String accessManager = options.get( URL_ACCESS_DECISION_MANAGER_KEY );

        return loadConfigClazz( accessManager, ResourceDecisionManager.class );
    }

    private VotingStrategy getURLVotingStrategy( final Map<String, String> options ) {
        final String votingStrategy = options.get( URL_VOTING_MANAGER_KEY );

        if ( votingStrategy == null || votingStrategy.isEmpty() ) {
            return new ConsensusBasedVoter();
        }

        return loadConfigClazz( votingStrategy, VotingStrategy.class );
    }

    private AuthorizationManager getAuthorizationManager( final Map<String, String> options ) {
        final String autzhManager = options.get( AUTHZ_MANAGER_KEY );

        return loadConfigClazz( autzhManager, AuthorizationManager.class );
    }

    private ResourceManager getResourceManager( final Map<String, String> options ) {
        final String resManager = options.get( RESOURCE_MANAGER_KEY );

        if ( resManager == null || resManager.isEmpty() ) {
            final String configFile = options.get( RESOURCE_MANAGER_CONFIG_KEY );

            return new URLResourceManager( configFile );
        }

        return loadConfigClazz( resManager, ResourceManager.class );
    }

    private AuthenticationProvider getAuthenticationProvider( final Map<String, String> options ) {
        final String authProvider = options.get( AUTH_PROVIDER_KEY );

        return loadConfigClazz( authProvider, AuthenticationProvider.class );
    }

    private AuthenticationManager getAuthenticationManager( final Map<String, String> options ) {
        final String authManager = options.get( AUTH_MANAGER_KEY );

        return loadConfigClazz( authManager, AuthenticationManager.class );
    }

    private AuthenticationScheme getAuthenticationScheme( final Map<String, String> options ) {
        final String authScheme = options.get( AUTH_SCHEME_KEY );
        AuthenticationScheme scheme = null;
        if ( authScheme == null || authScheme.isEmpty() ) {
            return new FormAuthenticationScheme();
        } else {
            scheme = loadConfigClazz( authScheme, AuthenticationScheme.class );
        }

        if ( scheme == null && authScheme.equalsIgnoreCase( FORM ) ) {
            return new FormAuthenticationScheme();
        }

        return scheme;
    }

    @Override
    public void doFilter( final ServletRequest request,
                          final ServletResponse rawResponse,
                          final FilterChain chain )
            throws IOException, ServletException {

        final HttpServletRequest httpRequest = (HttpServletRequest) request;
        final HttpServletResponse httpResponse = new HttpServletResponseWrapper((HttpServletResponse) rawResponse);

        final SecurityContext context = securityManager.newSecurityContext( httpRequest, httpResponse );

        try {
            logout( context, httpRequest, httpResponse );

            authenticate( context, httpResponse );

            authorize( context, httpResponse );

            if ( !httpResponse.isCommitted() ) {
                chain.doFilter( request, httpResponse );
            }
        } catch ( AuthenticationException e ) {
            if ( !httpResponse.isCommitted() ) {
                LOG.debug("Authentication failure. Sending HTTP 401 response.", e);
                httpResponse.sendError( 401, e.getMessage() );
            }
            else {
              LOG.debug("Authentication failure on already-committed response. NOT sending HTTP 401.", e);
            }
        }
    }

    private void logout( final SecurityContext context,
                         final HttpServletRequest httpRequest,
                         final HttpServletResponse httpResponse ) {
        if ( httpResponse.isCommitted() ) {
            return;
        }

        if ( isLogoutRequest( httpRequest ) ) {
            securityManager.logout( context );
            try {
                httpResponse.sendRedirect( getBaseUrl( httpRequest ) );
            } catch ( IOException e ) {
                LOG.error( "Can't redirect. Message: " + e.toString() );
            }
        }
    }

    private String getBaseUrl( HttpServletRequest request ) {
        if ( ( request.getServerPort() == 80 ) ||
                ( request.getServerPort() == 443 ) ) {
            return request.getScheme() + "://" +
                    request.getServerName() +
                    request.getContextPath();
        } else {
            return request.getScheme() + "://" +
                    request.getServerName() + ":" + request.getServerPort() +
                    request.getContextPath();
        }
    }

    private boolean isLogoutRequest( final HttpServletRequest request ) {
        return request.getRequestURI().contains( LOGOUT_URI );
    }

    private void authenticate( final SecurityContext context,
                               final HttpServletResponse httpResponse )
            throws AuthenticationException {
        if ( httpResponse.isCommitted() ) {
            return;
        }

        final Subject subject = securityManager.authenticate( context );
        SecurityFactory.setSubject( subject );
    }

    private void authorize( final SecurityContext context,
                            final HttpServletResponse httpResponse )
            throws IOException {
        if ( httpResponse.isCommitted() ) {
            return;
        }

        boolean authorize = securityManager.authorize( context );

        if ( !authorize && !httpResponse.isCommitted() ) {
            httpResponse.sendError( SC_FORBIDDEN );
        }
    }

    private <T> T loadConfigClazz( final String clazzName,
                                   final Class<T> typeOf ) {

        if ( clazzName == null || clazzName.isEmpty() ) {
            return null;
        }

        try {
            final Class<?> clazz = Class.forName( clazzName );

            if ( !typeOf.isAssignableFrom( clazz ) ) {
                LOG.error( "Invalid class type '" + typeOf.getName() + "'" );
                return null;
            }

            return typeOf.cast( clazz.newInstance() );
        } catch ( ClassNotFoundException e ) {
            LOG.error( "Class not found '" + clazzName + "'" );
        } catch ( InstantiationException e ) {
            LOG.error( "Can't instantiate class '" + clazzName + "'" );
        } catch ( IllegalAccessException e ) {
            LOG.error( "The following error ocurred. " + e.getMessage() );
        }

        return null;
    }

    @Override
    public void destroy() {
        securityManager.dispose();
    }
}
TOP

Related Classes of org.uberfire.security.server.UberFireSecurityFilter

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.