001    /*
002     * Copyright (c) 2002-2005 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.security.remoting;
017    
018    import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
019    import org.springframework.remoting.httpinvoker.HttpInvokerRequestExecutor;
020    import org.springframework.richclient.security.AuthenticationAware;
021    import org.springframework.security.Authentication;
022    
023    /**
024     * Extension of <code>HttpInvokerProxyFactoryBean</code> that supports the use of BASIC
025     * authentication on each HTTP request. This factory takes care of instantiating the
026     * proper invocation executor, {@link BasicAuthHttpInvokerRequestExecutor}, and keeping
027     * it up to date with the latest user credentials. Once a more complete AOP implementation
028     * is available, then this "token forwarding" can be removed as the default executor is
029     * already wired to receive notifications when it is constructed by the application
030     * context.
031     * <p>
032     * This configuration assumes that the user's credentials are "global" to the application
033     * and every invocation should use the same credentials. If you need per-thread
034     * authentication then you should look at using a combination of
035     * {@link HttpInvokerProxyFactoryBean} and
036     * {@link org.springframework.security.context.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor}.
037     * <p>
038     * {@link AuthenticationAware} is implemented in order to get notifications of changes in
039     * the user's credentials. Please see the class documentation for
040     * <code>AuthenticationAware</code> to see how to configure the application context so
041     * that authentication changes are broadcast properly.
042     * <p>
043     * @author Larry Streepy
044     */
045    public class BasicAuthHttpInvokerProxyFactoryBean extends HttpInvokerProxyFactoryBean implements AuthenticationAware {
046    
047        /**
048         * Constructor. Install the default executor.
049         */
050        public BasicAuthHttpInvokerProxyFactoryBean() {
051            setHttpInvokerRequestExecutor( new BasicAuthHttpInvokerRequestExecutor() );
052        }
053    
054        //
055        // === AuthenticationAware implementation ===
056        //
057    
058        /**
059         * Handle a change in the current authentication token. Pass it along to the executor
060         * if it's of the proper type.
061         * @see BasicAuthHttpInvokerRequestExecutor
062         * @see AuthenticationAware#setAuthenticationToken(org.springframework.security.Authentication)
063         */
064        public void setAuthenticationToken(Authentication authentication) {
065            if( logger.isDebugEnabled() ) {
066                logger.debug( "New authentication token: " + authentication );
067            }
068    
069            final HttpInvokerRequestExecutor hire = getHttpInvokerRequestExecutor();
070            if( hire instanceof BasicAuthHttpInvokerRequestExecutor ) {
071                if( logger.isDebugEnabled() ) {
072                    logger.debug( "Pass it along to executor" );
073                }
074                ((BasicAuthHttpInvokerRequestExecutor) hire).setAuthenticationToken( authentication );
075            }
076        }
077    }