Announcement Announcement Module
Collapse
No announcement yet.
Basic authentication and HttpInvoker Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Basic authentication and HttpInvoker

    I just threw together a quick and dirty pair of convenience classes for setting up an HttpInvokerProxyFactory that sends basic authentication with each request to the HTTP service. I'll share them in case others find them useful. I should note that this implementation could probably be spruced up a little. :-)

    First, we need a BasicAuthenticationInvokerRequestExecutor. This uses common's HttpClient, so there will be that dependency in your code if you go this route:

    Code:
    public class BasicAuthenticationInvokerRequestExecutor extends CommonsHttpInvokerRequestExecutor
        implements AuthorizationAware
    {
      private static final Log log = LogFactory.getLog(BasicAuthenticationInvokerRequestExecutor.class);
    
      private String username;
      private String password;
    
      private boolean httpClientStateSet = false;
    
      public HttpClient getHttpClient()
      {
        HttpClient ret = super.getHttpClient();
        if(ret == null) {
          setHttpClient((ret = new HttpClient()));
        }
        return ret;
      }
    
      public synchronized String getUsername()
      {
        return this.username;
      }
    
      public synchronized void setUsername(final String username)
      {
        this.username = username;
        this.httpClientStateSet = false;
      }
    
      public synchronized String getPassword()
      {
        return this.password;
      }
    
      public synchronized void setPassword(final String password)
      {
        this.password = password;
        this.httpClientStateSet = false;
      }
    
      protected RemoteInvocationResult doExecuteRequest(
          final HttpInvokerClientConfiguration config, final ByteArrayOutputStream baos) throws IOException,
          ClassNotFoundException
      {
        synchronized(this) {
          if(!this.httpClientStateSet) {
            final HttpClient client = getHttpClient();
            final URI uri;
            try {
              uri = new URI(config.getServiceUrl());
            } catch(URISyntaxException e) {
              final IOException ioe = new IOException();
              ioe.initCause(e);
              throw ioe;
            }
            if(getUsername() != null) {
              client.getState().setCredentials(null, uri.getHost(), new UsernamePasswordCredentials(getUsername(), getPassword()));
              client.getState().setAuthenticationPreemptive(true);
            } else {
              client.getState().setCredentials(null, uri.getHost(), null);
              client.getState().setAuthenticationPreemptive(false);
            }
            this.httpClientStateSet = true;
          }
        }
        return super.doExecuteRequest(config, baos);
      }
    
    
      //
      // METHODS FROM INTERFACE AuthorizationAware
      //
    
      public void setUserAttemptedAuthorization(final String principal,
                                                final String credentials)
      {
      }
    
      public synchronized void setUserAuthorization(final String principal, final String credentials)
      {
        if(log.isDebugEnabled()) log.debug(">>- setUserAuthorization invoked in BasicAuthenticationInvokerRequestExecutor for principal '" + principal + "'");
        setUsername(principal);
        setPassword(credentials);
      }
    }
    Some notes on this class: the AuthorizationAware interface is my own interface. We have a bean in the app context that automatically injects authorization info into beans implementing this interface whenever a user logs in or out (this is in a rich client app). So, when the user logs in the username and password are automatically set on this RequestExecutor. In order to reuse this class for your own purposes, you will either need to create your own AuthorizationAware interface or remove the interface (and the two related methods) from this code and manually call setUsername/setPassword. Also note that this implemention creates a default HttpClient, but that you can set your own instance and override the default. You may also want to tweak the way this class sets up authorization on the HttpClient state.
    You could just use this class directly with HttpInvokerProxyFactoryBean and be done with it... but we wanted to make our life just that much easier, so we created a convenience HttpInvokerProxyFactoryBean that default to using BasicAuthenticationInvokerRequestExecutor and also forwards AuthorizationAware injections to the internal request executor:
    Code:
    public class BasicAuthHttpInvokerProxyFactoryBean extends HttpInvokerProxyFactoryBean
        implements AuthorizationAware
    {
      private static final Log log = LogFactory.getLog(BasicAuthHttpInvokerProxyFactoryBean.class);
    
      private boolean doNotRemoteObjectMethods = true;
    
      public BasicAuthHttpInvokerProxyFactoryBean()
      {
        setHttpInvokerRequestExecutor(new BasicAuthenticationInvokerRequestExecutor());
      }
    
      public void setUsername(final String username)
      {
        final HttpInvokerRequestExecutor hire = getHttpInvokerRequestExecutor();
        if(hire instanceof BasicAuthenticationInvokerRequestExecutor) {
          ((BasicAuthenticationInvokerRequestExecutor)hire).setUsername(username);
        }
      }
    
      public void setPassword(final String password)
      {
        final HttpInvokerRequestExecutor hire = getHttpInvokerRequestExecutor();
        if(hire instanceof BasicAuthenticationInvokerRequestExecutor) {
          ((BasicAuthenticationInvokerRequestExecutor)hire).setPassword(password);
        }
      }
    
      /**
       * Determines if the proxy returned by this FactoryBean should remotely
       * invoke methods inherited from java.lang.Object.  If true, then the
       * methods are invoked against the Proxy class itself, otherwise the
       * methods will be invoked on the remote service.  Default is true.
       * @return
       */
      public boolean getDoNotRemoteObjectMethods()
      {
        return this.doNotRemoteObjectMethods;
      }
    
      public void setDoNotRemoteObjectMethods(final boolean doNotRemoteObjectMethods)
      {
        this.doNotRemoteObjectMethods = doNotRemoteObjectMethods;
      }
    
    
    
      //
      // METHODS FROM CLASS HttpInvokerProxyFactoryBean
      //
    
      public Object invoke(final MethodInvocation methodInvocation) throws Throwable
      {
        if(this.doNotRemoteObjectMethods &&
           Object.class.equals(methodInvocation.getMethod().getDeclaringClass())) {
          if(log.isDebugEnabled()) log.debug("==>> java.lang.Object method invoked on remote proxy '" + getServiceUrl() + "', calling on local object instead of remote: " + methodInvocation.getMethod());
          return methodInvocation.getMethod().invoke(this, methodInvocation.getArguments());
        }
        return super.invoke(methodInvocation);
      }
    
    
    
      //
      // METHODS FROM INTERFACE AuthorizationAware
      //
    
      public void setUserAttemptedAuthorization(final String principal,
                                                final String credentials)
      {
        final HttpInvokerRequestExecutor hire = getHttpInvokerRequestExecutor();
        if(hire instanceof AuthorizationAware) {
          ((AuthorizationAware)hire).setUserAttemptedAuthorization(principal, credentials);
        }
      }
    
      public void setUserAuthorization(final String principal, final String credentials)
      {
        final HttpInvokerRequestExecutor hire = getHttpInvokerRequestExecutor();
        if(hire instanceof AuthorizationAware) {
          ((AuthorizationAware)hire).setUserAuthorization(principal, credentials);
        }
      }
    }
    This class also provides setUsername/setPassword methods, and just forwards them to the internal request executor.
    NOTE: one major difference between this class and HttpInvokerProxyFactoryBean is that it defaults to NOT remoting methods defined in java.lang.Object. In other words, if someone calls toString() (for example) on the remote proxy then the call will not be sent to the remote service but rather executed against the proxy factory bean instead. This can be changed by explicitly setting the doNotRemoteObjectMethods property to false.

    - Andy

  • #2
    Re: Basic authentication and HttpInvoker

    First of all, an interesting extension! I'll have a more detailed look at it later; we should probably add such support to the standard HTTP invoker.

    Originally posted by adepue
    NOTE: one major difference between this class and HttpInvokerProxyFactoryBean is that it defaults to NOT remoting methods defined in java.lang.Object. In other words, if someone calls toString() (for example) on the remote proxy then the call will not be sent to the remote service but rather executed against the proxy factory bean instead. This can be changed by explicitly setting the doNotRemoteObjectMethods property to false.
    Note that I recently changed equals/hashCode/toString to be handled locally, both for HTTP invokers and RMI invokers, following a suggestion in another forum thread. So as of Spring 1.1.2, those methods will always be handled locally; Hessian and Burlap behave the same, BTW. I consider it a bug that HTTP/RMI invoker haven't behaved that way before.

    Juergen

    Comment


    • #3
      An additional extension to HttpInvoker is now included with Acegi Security CVS as well. Because it's so short I thought I'd share its approach here:

      Code:
      public class AuthenticationSimpleHttpInvokerRequestExecutor
          extends SimpleHttpInvokerRequestExecutor {
          private static final Log logger = LogFactory.getLog(AuthenticationSimpleHttpInvokerRequestExecutor.class);
      
          protected void prepareConnection(HttpURLConnection con, int contentLength)
              throws IOException, AuthenticationCredentialsNotFoundException {
              super.prepareConnection(con, contentLength);
      
              if ((ContextHolder.getContext() == null)
                  || !(ContextHolder.getContext() instanceof SecureContext)) {
                  throw new AuthenticationCredentialsNotFoundException(
                      "ContextHolder is null or does not contain a SecureContext");
              }
      
              Authentication auth = ((SecureContext) ContextHolder.getContext())
                  .getAuthentication();
      
              if ((auth == null) || (auth.getPrincipal() == null)
                  || (auth.getCredentials() == null)) {
                  throw new AuthenticationCredentialsNotFoundException(
                      "The Authentication contained in the ContextHolder is null or the principal and/or credentials properties are null");
              }
      
              String base64 = auth.getPrincipal().toString() + ":"
                  + auth.getCredentials().toString();
              con.setRequestProperty("Authorization",
                  "Basic " + new String(Base64.encodeBase64(base64.getBytes())));
      
              if (logger.isDebugEnabled()) {
                  logger.debug(
                      "HttpInvocation now presenting via BASIC authentication ContextHolder-derived: "
                      + auth.toString());
              }
          }
      }
      This lets Acegi Security users automatically propagate the security identity from their local ContextHolder. This might be especially useful if using the run-as replacement capabilities. Acegi Security also offers transparent transmission of the ContextHolder to the server in the case of RMI.

      Thanks for the HttpInvoker flexibility, Juergen.

      Comment


      • #4
        Hello,

        I am curious to know if the HttpInvoker extension has been rolled into CVS...if not then I guess I'll copy/paste this example until the ability to specify a username/password for an HTTP remote call is provided by Spring.

        Thanks!
        Patrick

        Comment


        • #5
          Andy,

          According your suggestion, I have create a bean that looks up my client-context for AuthorizationAware beans and sets creditional on it. But for some reason I am not able to look them on applicationContext, here is my code snippet for looking up these BasicAuthHttpInvokerProxyFactoryBean that implement AuthorizationAware interface.
          Code:
                  ApplicationContext applicationContext = Application.services().getApplicationContext();
                  
                  Map map = applicationContext.getBeansOfType(AuthorizationAware.class, false, true);
          But my map is empty. Do you know why? BTW i can look up these beans by name or if I use factory class name i.e. "BasicAuthHttpInvokerProxyFactoryBean" then its works fine but not by interface?

          I am sure you must have encountered the same issue and was wondering how did you resolve it.

          Amad

          Comment


          • #6
            At this point, it's probably a good idea to post my latest AuthorizationAwareConfigurer class. I believe we've wrestled in the past with a couple of issues related to the usage pattern I spoke of earlier, and this AuthorizationAwareConfigurer should show how we've worked through the issues. I'm going to post the code as-is, even though it is not commented. I'll also leave the debug statements in, as they can be a little descriptive of what's going on...
            Code:
            import org.springframework.context.ApplicationListener;
            import org.springframework.context.ApplicationEvent;
            import org.springframework.context.ApplicationContextAware;
            import org.springframework.context.ApplicationContext;
            import org.springframework.richclient.security.LoginEvent;
            import org.springframework.richclient.security.LogoutEvent;
            import org.springframework.richclient.security.ClientSecurityEvent;
            import org.springframework.beans.BeansException;
            import org.springframework.beans.factory.config.BeanPostProcessor;
            import org.springframework.beans.factory.BeanIsNotAFactoryException;
            import org.springframework.beans.factory.BeanIsAbstractException;
            import org.apache.commons.logging.Log;
            import org.apache.commons.logging.LogFactory;
            import net.sf.acegisecurity.Authentication;
            
            import java.util.Map;
            import java.util.Iterator;
            import java.util.List;
            import java.util.Collections;
            import java.util.LinkedList;
            import java.lang.ref.WeakReference;
            
            /**
             * Whenever a user logs in this component will find all beans that implement
             * AuthorizationAware in the Spring ApplicationContext and notify them of
             * the new authorization information.
             */
            public class AuthorizationAwareConfigurer implements ApplicationListener,
                                                                 ApplicationContextAware,
                                                                 BeanPostProcessor
            {
              private static final Log log = LogFactory.getLog(AuthorizationAwareConfigurer.class);
            
              private ApplicationContext applicationContext;
            
              private String currentPrincipal;
              private String currentCredentials;
              private boolean currentAttempting = false;
            
              private final List nonSingletonListeners = Collections.synchronizedList(new LinkedList());
            
              public ApplicationContext getApplicationContext()
              {
                return this.applicationContext;
              }
            
              protected void addToNonSingletonListeners(final AuthorizationAware aa)
              {
                if(log.isDebugEnabled()) log.debug(">>> Adding AuthorizationAware bean '" + aa + "' to list of non singleton listeners.");
                this.nonSingletonListeners.add(new WeakReference(aa));
              }
            
              protected void updateBean(final AuthorizationAware aa, final String principal, final String credentials, final boolean attempting, final boolean postOp)
              {
                if(log.isDebugEnabled()) log.debug(">>> Notifying bean '" + aa + "' of new authorization for '" + principal + "'");
                if(attempting) {
                  aa.setUserAttemptedAuthorization(principal, credentials);
                } else {
                  if(!postOp) {
                    aa.setUserAuthorization(principal, credentials);
                  } else {
                    aa.setPostUserAuthorization(principal, credentials);
                  }
                }
              }
            
              protected void updateBeans(final String principal, final String credentials,
                                         final boolean attempting, final boolean postOp)
              {
                if(log.isDebugEnabled()) log.debug(">> ENTERING updateBean(principal='" + principal + "', credentials=PROTECTED, attempting=" + attempting);
                this.currentPrincipal = principal;
                this.currentCredentials = credentials;
                this.currentAttempting = attempting;
            
                final ApplicationContext ac = getApplicationContext();
            
                if(ac != null) {
                  if(log.isDebugEnabled()) log.debug(">> Notifying non factory beans...");
                  final Map map = ac.getBeansOfType(AuthorizationAware.class, false, true);
                  if(log.isDebugEnabled()) log.debug(">> AuthorizationAware BEANS=" + map);
                  final Iterator iEntries = map.entrySet().iterator();
                  while(iEntries.hasNext()) {
                    final Map.Entry entry = (Map.Entry)iEntries.next();
                    final Object bean = entry.getValue();
            
                    if(bean instanceof AuthorizationAware) {
                      if(log.isDebugEnabled()) log.debug(">> Setting authorization information on bean name='" + entry.getKey() + "', bean='" + bean + "'");
                      updateBean((AuthorizationAware)bean, principal, credentials, attempting, postOp);
                    }
                  }
            
                  if(log.isDebugEnabled()) log.debug(">> Notifying factory beans...");
                  final String[] names = ac.getBeanDefinitionNames();
                  final StringBuffer factoryBuf = new StringBuffer();
                  factoryBuf.append("&");
                  for(final String beanName : names) {
                    factoryBuf.setLength(1);
                    factoryBuf.append(beanName);
                    final String factoryName = factoryBuf.toString();
                    try {
                      if(ac.containsBean(factoryName) && ac.isSingleton(factoryName) &&
                         ac.isSingleton(beanName)) {
                        final Object factoryBean = ac.getBean(factoryName);
                        if(factoryBean instanceof AuthorizationAware) {
                          if(log.isDebugEnabled()) log.debug(">> Bean '" + beanName + "' is a factory bean implementing AuthorizationAware, setting auth info for principal '" + principal + "'");
                          updateBean((AuthorizationAware)factoryBean, principal, credentials, attempting, postOp);
                        }
                      }
                    } catch(BeanIsNotAFactoryException binafe) {
                      // Just skip it then...
                    } catch(BeanIsAbstractException biae) {
                    }
                  }
            
                  if(log.isDebugEnabled()) log.debug(">> Notifying non-singleton beans...");
                  updateNonSingletonBeans(principal, credentials, attempting, postOp);
                }
              }
            
              protected void updateNonSingletonBeans(final String principal, final String credentials,
                                                     final boolean attempting, final boolean postOp)
              {
                synchronized(this.nonSingletonListeners) {
                  for(Iterator iNonSingletons = this.nonSingletonListeners.iterator(); iNonSingletons.hasNext();) {
                    final WeakReference weakReference = (WeakReference) iNonSingletons.next();
                    final AuthorizationAware aa = (AuthorizationAware)weakReference.get();
                    if(aa == null) {
                      if(log.isDebugEnabled()) log.debug(">> JUST REMOVED garbage collected AuthorizationAware non-singleton from list.");
                      iNonSingletons.remove();
                    } else {
                      if(log.isDebugEnabled()) log.debug(">> UPDATING non-singleton AuthorizationAware instance '" + aa + "'");
                      updateBean(aa, principal, credentials, attempting, postOp);
                    }
                  }
                }
              }
            
            
              //
              // METHODS FROM INTERFACE ApplicationListener
              //
            
              public void onApplicationEvent(final ApplicationEvent event)
              {
                if(event instanceof ClientSecurityEvent) {
                  if(log.isDebugEnabled()) log.debug(">> RECEIVED ClientSecurityEvent: " + event);
                  if(event instanceof LoginEvent ||
                     event instanceof AttemptingAuthorizationEvent) {
                    Authentication authentication = (Authentication)event.getSource();
                    if(log.isDebugEnabled()) log.debug(">> Authentication = " + authentication);
                    updateBeans(authentication.getPrincipal().toString(),
                                authentication.getCredentials().toString(),
                                event instanceof AttemptingAuthorizationEvent,
                                false);
                  } else if(event instanceof LogoutEvent) {
                    if(log.isDebugEnabled()) log.debug(">> This is a LogoutEvent");
                    updateBeans(null, null, false, false);
                  } else if(event instanceof PostLoginEvent) {
                    Authentication authentication = (Authentication)event.getSource();
                    updateBeans(authentication.getPrincipal().toString(),
                                authentication.getCredentials().toString(),
                                false, true);
                  } else if(event instanceof PostLogoutEvent) {
                    updateBeans(null, null, false, true);
                  }
                }
              }
            
            
            
              //
              // METHODS FROM INTERFACE ApplicationContextAware
              //
            
              public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException
              {
                this.applicationContext = applicationContext;
              }
            
            
              //
              // METHODS FROM INTERFACE BeanPostProcessor
              //
            
              public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException
              {
                if(bean instanceof AuthorizationAware) {
                  if(beanName == null || !getApplicationContext().containsBean(beanName) ||
                     !getApplicationContext().isSingleton(beanName)) {
                    addToNonSingletonListeners((AuthorizationAware)bean);
                  }
                  updateBean((AuthorizationAware)bean, this.currentPrincipal, this.currentCredentials, this.currentAttempting, false);
                }
                return bean;
              }
            
              public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
              {
                return bean;
              }
            }
            As you can see from this code, we have run into issues with factory beans implementing AuthorizationAware, and have a kind of hacky workaround. At the time this code was written, Spring did not provide methods for finding factory beans that implement a certain interface (as opposed to factory beans whose returned bean implements a certain interface), thus the hackiness. It could be that newer versions of Spring offer more in this area now? You can see that the code goes through a two-step process: first handling non-factory beans, then handling factory beans. Also, this code handles non-singleton beans by keeping them in a collection as they are created using weak references. Finally, it appears that some of the newer code (aka, the factory bean fix code) uses newer Java 1.5 syntax (we recently made the decision to go with Java 1.5, so we've been writing any new code with new syntax).

            Comment


            • #7
              Thanks Andy

              Amad

              Comment


              • #8
                Andy is it possible that you can post your latest AuthorizationAware and AttemptingAuthorizationEvent as well?

                amad

                Comment


                • #9
                  We've customized AuthorizationAware to our own needs (in our rich client), but I'll post it here nonetheless:
                  Code:
                  /**
                   * A Spring managed bean implementing this interface will be automatically
                   * notified of the user's information once they have logged in if there is
                   * a singleton non-lazy instance of {@link AuthorizationAwareConfigurer}
                   * defined in the Spring ApplicationContext.
                   */
                  public interface AuthorizationAware
                  {
                    /**
                     * Called before attempting to authorize the specified principal and
                     * credentials.
                     * 
                     * @param principal
                     * @param credentials
                     */
                    public void setUserAttemptedAuthorization(final String principal, final String credentials);
                  
                    /**
                     * Called once the user has been successfully authenticated.
                     * @param principal
                     * @param credentials
                     */
                    public void setUserAuthorization(final String principal, final String credentials);
                  
                    /**
                     * Called once the user has been successfully authenticated, and after all
                     * AuthorizationAware beans have had 
                     * {@link #setUserAuthorization(String, String)} invoked.
                     * @param prinicipal
                     * @param credentials
                     */ 
                    public void setPostUserAuthorization(final String prinicipal, final String credentials);
                  }
                  We needed the ability for certain beans to be notified of the user's authorization information after all other beans had been notified, thus the setPostUserAuthorization method. The system does nothing more, in effect, than call setUserAuthorization on all beans and then setPostUserAuthorization on all beans. Not super elegant, but simple and it works.

                  Here is AttemptingAuthorizationEvent:
                  Code:
                  import org.springframework.richclient.security.ClientSecurityEvent;
                  import net.sf.acegisecurity.Authentication;
                  
                  /**
                   * Fired when the system is about to attempt authorization.
                   */
                  public class AttemptingAuthorizationEvent extends ClientSecurityEvent
                  {
                    public AttemptingAuthorizationEvent(final Authentication authentication)
                    {
                      super(authentication);
                    }
                  }
                  Very simple, as you can see. We needed to be aware when a user was attempting authorization, but before being authorized. The real usefulness is in actually firing this event at the appropriate time. We use a custom LoginCommand and LogoutCommand (with associated LoginForm and SessionDetails). Here is the relevant code from our version of SessionDetails.login():
                  Code:
                  ...
                      // Attempt login
                      UsernamePasswordAuthenticationToken request = new UsernamePasswordAuthenticationToken(
                          principal, getPassword());
                  
                      final ApplicationContext appCtx = Application.services().getApplicationContext();
                      appCtx.publishEvent(new AttemptingAuthorizationEvent(request));
                  
                      final Authentication result;
                      try {
                        result = authenticationManager.authenticate(request);
                      } catch(Throwable t) {
                        log.warn("Authentication for '" + principal + "' failed", t);
                        appCtx.publishEvent(new LogoutEvent(request));
                        if(t instanceof AuthenticationException) {
                          throw (AuthenticationException)t;
                        }
                        throw new BadCredentialsException("Authentication failed.", t);
                      }
                  
                      // Setup a secure ContextHolder (if required)
                      if(ContextHolder.getContext() == null
                         || !(ContextHolder.getContext() instanceof SecureContext)) {
                        try {
                          ContextHolder.setContext((SecureContext) getSecureContextClass()
                                                                   .newInstance());
                        } catch(Exception e) {
                          throw new RuntimeException(e);
                        }
                      }
                  
                      // Commit the successful Authentication object to the secure
                      // ContextHolder
                      SecureContext sc = (SecureContext) ContextHolder.getContext();
                      sc.setAuthentication(result);
                      ContextHolder.setContext(sc);
                  
                      // Fire application event to advise of new login
                      appCtx.publishEvent(new LoginEvent(result));
                      appCtx.publishEvent(new PostLoginEvent(result));
                  Feel free to totally remove the PostLoginEvent if you have no need for it. The same goes for AttemptingAuthorizationEvent as well. If you do want PostLoginEvent, then it is pretty easy to recreate (it is the same as AttemptingAuthorizationEvent). PostLoginEvent is useful if you have AuthorizationAware beans that invoke other beans when a user is authenticated, those other beans are AuthorizationAware, and you need to be guaranteed that the user auth info will be set on the depended-upon beans before the dependent bean (if that makes sense). An example would be a bean that invokes a service (http invoker service) once the user is authenticated. You want to be sure that the http invoker has had the user's authorization set before you attempt to invoke it - so, you would put your dependent code in the setPostUserAuthorization method. We structure our code so that service providing AuthorizationAware beans react to setUserAuthorization and service consuming AuthorizationAware beans react to setPostUserAuthorization. At this point it might be a better idea to refactor the idea a little (maybe use straight ApplicationEvents) - however, this is how it has evolved, it works, and for us refactoring would not gain much at this point. So, here it is, warts and all.

                  Comment


                  • #10
                    Great, Thanks, Andy.

                    amad

                    Comment


                    • #11
                      AuthorizationAware or "I call you"

                      This thread is really great. Thanks Andy and Amad.

                      Having worked in a solution where beans ARE NOT aware of authorization, but rather a singleton KNOWS them and know what to hide/show enable/disable based in LoginEvents, I'm questioning my former approach.
                      In another post in the RC forum, I broght this some time ago.
                      But I'm stil in doubt and it is clear to me that it is not related to Spring RC capabilities. Or I shall say it is a matter of personal preference. The botton line is: what's the preferred approach: All relevants beans should be AuthorizationAware or as in the former approach, a third party should deal with this (a "I call you approach")?

                      Spring gurus, I listen and wish to learn from you!
                      Thanks in advance,
                      Gustavo.

                      Comment


                      • #12
                        Custom authentication and DIGEST

                        Hi guys,

                        Can anyone suggest how would this code differ if we would use a DIGEST algorithm for authentication.

                        Thank you,
                        Edmon

                        Comment


                        • #13
                          Never mind - here is the option for DIGEST

                          Never mind my previous post - I found it.
                          For DIGEST you would set this parameter on the client object:

                          Code:
                                  List authPrefs = new ArrayList(1);
                                  authPrefs.add(AuthPolicy.DIGEST);
                                  client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);

                          Comment


                          • #14
                            Http Remoting Authentication?

                            I see where there was a thread about this last October, but haven't noticed any recent discussion. I am also aware of the Acegi Security Framework for Spring, but that's really way more than what we're looking for right now.

                            Is it currently possible to have Http invoked services injected with some kind of authentication credential like a User object? I haven't been able to find any resources that describe how this might be done, if it's even part of the current Spring framework.

                            Thanks,
                            Dave

                            Comment

                            Working...
                            X